Control: tags -1 patch 

Hi, 

the attached patch adds std:: to all instances of isnan and isinf in
the c++ code, and this fixes the bug. 

Best, 
Gert 

--- a/core/Cell.cpp
+++ b/core/Cell.cpp
@@ -62,7 +62,7 @@
 	// spin tensor
 	W=.5*(gradV-gradV.transpose());
 	spinVec=.5*leviCivita(W);
-	// if(!isnan(nnextGradV(0,0))){ nextGradV=nnextGradV; nnextGradV<<NaN,NaN,NaN, NaN,NaN,NaN, NaN,NaN,NaN; }
+	// if(!std::isnan(nnextGradV(0,0))){ nextGradV=nnextGradV; nnextGradV<<NaN,NaN,NaN, NaN,NaN,NaN, NaN,NaN,NaN; }
 }
 
 Vector3r Cell::shearAlignedExtents(const Vector3r& perpExtent) const{
--- a/core/EnergyTracker.cpp
+++ b/core/EnergyTracker.cpp
@@ -11,7 +11,7 @@
 	// if ZeroDontCreate is set, the value is zero and no such energy exists, it will not be created and id will be still negative
 	if(id<0) findId(name,id,flg,/*newIfNotFound*/!(val==0. && (flg&ZeroDontCreate)));
 	if(id>=0){
-		if(isnan(val)){ LOG_WARN("Ignoring attempt to add NaN to energy '"<<name<<"'."); return; }
+		if(std::isnan(val)){ LOG_WARN("Ignoring attempt to add NaN to energy '"<<name<<"'."); return; }
 		energies.add(id,val);
 	}
 }
--- a/core/MatchMaker.cpp
+++ b/core/MatchMaker.cpp
@@ -10,7 +10,7 @@
 		if(((int)m[0]==id1 && (int)m[1]==id2) || ((int)m[0]==id2 && (int)m[1]==id1)) return m[2];
 	}
 	// no match
-	if(fbNeedsValues && (isnan(val1) || isnan(val2))) throw std::invalid_argument("MatchMaker: no match for ("+lexical_cast<string>(id1)+","+lexical_cast<string>(id2)+"), and values required for algo computation '"+algo+"' not specified.");
+	if(fbNeedsValues && (std::isnan(val1) || std::isnan(val2))) throw std::invalid_argument("MatchMaker: no match for ("+lexical_cast<string>(id1)+","+lexical_cast<string>(id2)+"), and values required for algo computation '"+algo+"' not specified.");
 	return computeFallback(val1,val2);
 }
 
--- a/core/Scene.cpp
+++ b/core/Scene.cpp
@@ -331,7 +331,7 @@
 		// checkStateTypes();
 	}
 	// check and automatically set timestep
-	if(isnan(dt)||isinf(dt)||dt<0){
+	if(std::isnan(dt)||std::isinf(dt)||dt<0){
 		#if 0
 			throw std::runtime_error("Scene::dt is NaN, Inf or negative");
 		#else
@@ -350,7 +350,7 @@
 				LOG_INFO("Critical dt from "+f->pyStr()+": "<<crDt);
 				dt=min(dt,crDt);
 			}
-			if(isinf(dt)) throw std::runtime_error("Failed to obtain meaningful dt from engines and fields automatically.");
+			if(std::isinf(dt)) throw std::runtime_error("Failed to obtain meaningful dt from engines and fields automatically.");
 			dt=dtSafety*dt;
 		#endif
 	}
@@ -387,7 +387,7 @@
 		step++;
 		time+=dt;
 		subStep=-1;
-		if(!isnan(nextDt)){ dt=nextDt; nextDt=NaN; }
+		if(!std::isnan(nextDt)){ dt=nextDt; nextDt=NaN; }
 	} else {
 		/* IMPORTANT: take care to copy EXACTLY the same sequence as is in the block above !! */
 		if(TimingInfo::enabled){ TimingInfo::enabled=false; LOG_INFO("Master.timingEnabled disabled, since Master.subStepping is used."); }
@@ -415,7 +415,7 @@
 			else if(subs==(int)engines.size()){
 				if(isPeriodic) cell->setNextGradV();
 				step++; time+=dt; /* gives -1 along with the increment afterwards */ subStep=-2;
-				if(!isnan(nextDt)){ dt=nextDt; nextDt=NaN; }
+				if(!std::isnan(nextDt)){ dt=nextDt; nextDt=NaN; }
 			}
 			// (?!)
 			else { /* never reached */ assert(false); }
--- a/gui/qt4/GLViewer.cpp
+++ b/gui/qt4/GLViewer.cpp
@@ -887,7 +887,7 @@
 				Vector3r p3v(p3[0],p3[1],p3[2]); p3v[diri]=NaN;
 				for(short ax:{0,1,2}){
 					std::ostringstream oss;
-					oss<<(isnan(p3v[ax])?"*":to_string(p3v[ax]));
+					oss<<(std::isnan(p3v[ax])?"*":to_string(p3v[ax]));
 					glColor3v(Renderer::axisColor(ax));
 					QGLViewer::drawText(p.x()+20,p.y()+14*(ax+1),oss.str().c_str());
 				}
--- a/gui/qt4/OpenGLManager.cpp
+++ b/gui/qt4/OpenGLManager.cpp
@@ -41,7 +41,7 @@
 		frameMeasureTime=0;
 		t=1e-9*(woo::TimingInfo::getNow(/*evenIfDisabled*/true)-t); // in seconds
 		Real& dt(Renderer::fastDraw?Renderer::fastRenderTime:Renderer::renderTime);
-		if(isnan(dt)) dt=t;
+		if(std::isnan(dt)) dt=t;
 		dt=.6*dt+.4*(t);
 	} else {
 		frameMeasureTime++;
--- a/lib/base/CompUtils.cpp
+++ b/lib/base/CompUtils.cpp
@@ -133,7 +133,7 @@
 // return sample for cylindrical coordinate "box" uniformly-distributed in cartesian space; returned point is in cylindrical coordinates
 Vector3r CompUtils::cylCoordBox_sample_cylindrical(const AlignedBox3r& box, const Vector3r& unitRand){
 	// three random numbers; can be user-provided (for biased sampling), otherwise computed
-	Vector3r rand=isnan(unitRand.maxCoeff())?Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom()):unitRand;
+	Vector3r rand=std::isnan(unitRand.maxCoeff())?Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom()):unitRand;
 	// explanation at http://www.anderswallin.net/2009/05/uniform-random-points-in-a-circle-using-polar-coordinates/
 	const Real& r0(box.min()[0]); const Real& r1(box.max()[0]);
 	Real r=sqrt(pow(r0,2)+rand.x()*(pow(r1,2)-pow(r0,2)));
--- a/lib/opengl/GLUtils.cpp
+++ b/lib/opengl/GLUtils.cpp
@@ -34,7 +34,7 @@
 
 void GLUtils::AlignedBox(const AlignedBox3r& box, const Vector3r& color){
 	glPushMatrix();
-		if(!isnan(color[0])) glColor3v(color);
+		if(!std::isnan(color[0])) glColor3v(color);
 		glTranslatev(box.center().eval());
 		glScalev(Vector3r(box.max()-box.min()));
 		glDisable(GL_LINE_SMOOTH);
@@ -115,7 +115,7 @@
 		Quaternionr q(Quaternionr().setFromTwoVectors(Vector3r(0,0,1),(b-a)/dist /* normalized */));
 		// using Transform with OpenGL: http://eigen.tuxfamily.org/dox/TutorialGeometry.html
 		glMultMatrixd(Eigen::Affine3d(q).data());
-		if(!isnan(color[0]))	glColor3v(color);
+		if(!std::isnan(color[0]))	glColor3v(color);
 		gluQuadricDrawStyle(gluQuadric,wire?GLU_LINE:GLU_FILL);
 		if(stacks<0) stacks=max(1,(int)(dist/(rad1*(-stacks/10.))+.5));
 		gluCylinder(gluQuadric,rad1,rad2,dist,slices,stacks);
--- a/pkg/clDem/CLDemField.cpp
+++ b/pkg/clDem/CLDemField.cpp
@@ -189,8 +189,8 @@
 		if(shapeT==Shape_Sphere) mU=cp.shape.sphere.radius;
 		if(cp.mass>0) kgU=cp.mass;
 		bool kgFaked=false, mFaked=false; // use unit units, but reset back to NaN afterwards
-		if(isnan(kgU)){ kgU=1.; kgFaked=true; }
-		if(isnan(mU)){ mU=1.; mFaked=true; }
+		if(std::isnan(kgU)){ kgU=1.; kgFaked=true; }
+		if(std::isnan(mU)){ mU=1.; mFaked=true; }
 
 		// check that materials match
 		int matId=clDem::par_matId_get(&cp);
@@ -200,7 +200,7 @@
 			case clDem::Mat_ElastMat:{
 				if(!dynamic_pointer_cast< ::FrictMat>(yp->material)) _THROW_ERROR(pId<<": material mismatch ElastMat/"<<typeid(*(yp->material)).name());
 				const ::FrictMat& ym(yp->material->cast< ::FrictMat>());
-				if(!isinf(ym.tanPhi)) _THROW_ERROR(pId<<": woo::FrictMat::tanPhi="<<ym.tanPhi<<" should be infinity to represent frictionless clDem::ElastMat");
+				if(!std::isinf(ym.tanPhi)) _THROW_ERROR(pId<<": woo::FrictMat::tanPhi="<<ym.tanPhi<<" should be infinity to represent frictionless clDem::ElastMat");
 				const clDem::ElastMat& cm(sim->scene.materials[matId].mat.elast);
 				if(ym.density!=cm.density) _THROW_ERROR(pId<<": density differs "<<cm.density<<"/"<<ym.density);
 				if(ym.young!=cm.young) _THROW_ERROR(pId<<": young differes "<<cm.young<<"/"<<ym.young);
@@ -252,8 +252,8 @@
 	}
 
 	// in case we got no good units, use stupid values here
-	if(isnan(kgU)) kgU=1.;
-	if(isnan(mU)) mU=1.;
+	if(std::isnan(kgU)) kgU=1.;
+	if(std::isnan(mU)) mU=1.;
 	Real NU=kgU*mU/pow(sU,2); // force unit
 	
 
@@ -345,7 +345,7 @@
 				Real kNErr=abs(cc.phys.norm.kN-yp.kn)/(NU/mU);
 				_CHK_ERR(cId,kNErr,cc.phys.norm.kN,yp.kn);
 				// kT not checked
-				if(!isinf(yp.tanPhi)) _THROW_ERROR(cId<<": woo::FrictMat::tanPhi="<<yp.tanPhi<<" should be infinity to represent frictionless clDem::NormPhys");
+				if(!std::isinf(yp.tanPhi)) _THROW_ERROR(cId<<": woo::FrictMat::tanPhi="<<yp.tanPhi<<" should be infinity to represent frictionless clDem::NormPhys");
 				break;
 			}
 			case(clDem::Phys_FrictPhys):{
@@ -541,7 +541,7 @@
 	if(linEl6){
 		throw std::runtime_error("Law2_L6Geom_FrictPhys_LinEl6 not handled yet.");
 		sim->breakTension=false;
-		if(isnan(linEl6->charLen) || isinf(linEl6->charLen)) sim->charLen=NaN;
+		if(std::isnan(linEl6->charLen) || std::isinf(linEl6->charLen)) sim->charLen=NaN;
 	} else if(idealElPl){
 		sim->breakTension=true;
 		if(idealElPl->noSlip) throw std::runtime_error("Law2_L6Geom_FrictPhys_IdealElPl.noSlip==True not handled yet.");
@@ -585,7 +585,7 @@
 	// determine timestep here, if negative
 	if(sim->scene.dt<0){
 		sim->scene.dt=fabs(sim->scene.dt)*sim->pWaveDt();
-		if(isinf(sim->scene.dt)) throw std::runtime_error("Invalid p-wave timestep; are there no spherical particles in the simulation?");
+		if(std::isinf(sim->scene.dt)) throw std::runtime_error("Invalid p-wave timestep; are there no spherical particles in the simulation?");
 		std::cout<<"Note: setting Δt="<<sim->scene.dt<<endl;
 	}
 	
@@ -619,7 +619,7 @@
 			case clDem::Mat_FrictMat:{
 				if(mmatT==clDem::Mat_None) mmatT=clDem::Mat_FrictMat;
 				if(mmatT!=clDem::Mat_FrictMat) throw std::runtime_error("Combination of materials (ElastMat, FrictMat) not handled.");
-				//if(isnan(cmat.mat.frict.ktDivKn)) throw std::runtime_error("FrictMat.ktDivKn must not be NaN");
+				//if(std::isnan(cmat.mat.frict.ktDivKn)) throw std::runtime_error("FrictMat.ktDivKn must not be NaN");
 				auto fm=make_shared< ::FrictMat>();
 				fm->density=cmat.mat.frict.density;
 				fm->young=cmat.mat.frict.young;
@@ -644,7 +644,7 @@
 	collider->boundDispatcher->add(make_shared<Bo1_Sphere_Aabb>());
 	collider->boundDispatcher->add(make_shared<Bo1_Wall_Aabb>());
 	collider->boundDispatcher->add(make_shared<Bo1_Facet_Aabb>());
-	if(isnan(sim->scene.verletDist)) collider->dead=true;
+	if(std::isnan(sim->scene.verletDist)) collider->dead=true;
 	auto loop=make_shared<ContactLoop>();
 	loop->geoDisp->add(make_shared<Cg2_Sphere_Sphere_L6Geom>());
 	loop->geoDisp->add(make_shared<Cg2_Wall_Sphere_L6Geom>());
@@ -655,13 +655,13 @@
 	switch(mmatT){
 		case clDem::Mat_ElastMat:{
 			if(sim->breakTension){
-				if(!isnan(sim->charLen)) throw std::runtime_error("The combination of breaking contacts and non-NaN charLen (i.e. bending stiffness) is not handled yet!");
+				if(!std::isnan(sim->charLen)) throw std::runtime_error("The combination of breaking contacts and non-NaN charLen (i.e. bending stiffness) is not handled yet!");
 				auto law=make_shared<Law2_L6Geom_FrictPhys_IdealElPl>();
 				law->noSlip=true;
 				loop->lawDisp->add(law);
 			} else {
 				auto law=make_shared<Law2_L6Geom_FrictPhys_LinEl6>();
-				law->charLen=isnan(sim->charLen)?Inf:sim->charLen;
+				law->charLen=std::isnan(sim->charLen)?Inf:sim->charLen;
 				loop->lawDisp->add(law);
 			}
 			break;
@@ -797,7 +797,7 @@
 	}
 
 	// without collisions detection, potential contacts are given in advance
-	if(isnan(sim->scene.verletDist)){
+	if(std::isnan(sim->scene.verletDist)){
 		// potential contacts
 		for(const clDem::par_id2_t ids: sim->pot){
 			string cId="pot##"+lexical_cast<string>(ids.s0)+"+"+lexical_cast<string>(ids.s1);
--- a/pkg/dem/Clump.cpp
+++ b/pkg/dem/Clump.cpp
@@ -14,7 +14,7 @@
 	if(attr==NULL){
 		if(centers.size()!=radii.size()) throw std::runtime_error("SphereClumpGeom: centers and radii must have the same length (len(centers)="+to_string(centers.size())+", len(radii)="+to_string(radii.size())+").");
 		// valid data, and volume has not been computed yet
-		if(!centers.empty() && isnan(volume)) recompute(div);
+		if(!centers.empty() && std::isnan(volume)) recompute(div);
 	} else {
 		// centers/radii/div changed, try to recompute
 		recompute(div,/*failOk*/true,/*fastOnly*/true);
@@ -170,7 +170,7 @@
 	// sets particles in global space based on relPos, relOri
 	ClumpData::applyToMembers(n);
 	// set clump properties
-	assert(!isnan(volume));
+	assert(!std::isnan(volume));
 	cd->setClump(); assert(cd->isClump());
 	// scale = length scale (but not density scale)
 	cd->mass=mat->density*volume*pow(scale,3);
--- a/pkg/dem/Collision.cpp
+++ b/pkg/dem/Collision.cpp
@@ -66,7 +66,7 @@
 	} else {
 		Vector3r mn=aabb.min, mx=aabb.max;
 		// fit infinite bboxes into the cell, if needed
-		for(int ax:{0,1,2}){ if(isinf(mn[ax])) mn[ax]=0; if(isinf(mx[ax])) mx[ax]=scene->cell->getHSize().diagonal()[ax]; }
+		for(int ax:{0,1,2}){ if(std::isinf(mn[ax])) mn[ax]=0; if(std::isinf(mx[ax])) mx[ax]=scene->cell->getHSize().diagonal()[ax]; }
 		glTranslatev(Vector3r(scene->cell->shearPt(scene->cell->wrapPt(.5*(mn+mx)))));
 		glMultMatrixd(scene->cell->getGlShearTrsfMatrix());
 		glScalev(Vector3r(mx-mn));
--- a/pkg/dem/Concrete.cpp
+++ b/pkg/dem/Concrete.cpp
@@ -21,14 +21,14 @@
 
 	// check unassigned values
 	if (!mat1.neverDamage) {
-		assert(!isnan(mat1.sigmaT));
-		assert(!isnan(mat1.epsCrackOnset));
-		assert(!isnan(mat1.relDuctility));
+		assert(!std::isnan(mat1.sigmaT));
+		assert(!std::isnan(mat1.epsCrackOnset));
+		assert(!std::isnan(mat1.relDuctility));
 	}
 	if (!mat2.neverDamage) {
-		assert(!isnan(mat2.sigmaT));
-		assert(!isnan(mat2.epsCrackOnset));
-		assert(!isnan(mat2.relDuctility));
+		assert(!std::isnan(mat2.sigmaT));
+		assert(!std::isnan(mat2.epsCrackOnset));
+		assert(!std::isnan(mat2.relDuctility));
 	}
 
 	// particles sharing the same material; no averages necessary
@@ -209,8 +209,8 @@
 
 
 #define _WOO_VERIFY(condition) if(!(condition)){ throw std::runtime_error(__FILE__+string(":")+to_string(__LINE__)+": verification "+#condition+" failed, in contact "+C->pyStr()+"."); }
-#define NNAN(a) _WOO_VERIFY(!isnan(a));
-#define NNANV(v) _WOO_VERIFY(!isnan(v.maxCoeff()));
+#define NNAN(a) _WOO_VERIFY(!std::isnan(a));
+#define NNANV(v) _WOO_VERIFY(!std::isnan(v.maxCoeff()));
 
 WOO_IMPL_LOGGER(Law2_L6Geom_ConcretePhys);
 
--- a/pkg/dem/ContactLoop.cpp
+++ b/pkg/dem/ContactLoop.cpp
@@ -237,7 +237,7 @@
 		stress/=scene->cell->getVolume();
 		if(scene->trackEnergy){
 			Matrix3r midStress=.5*(stress+prevStress);
-			Real midVol=(!isnan(prevVol)?.5*(prevVol+scene->cell->getVolume()):scene->cell->getVolume());
+			Real midVol=(!std::isnan(prevVol)?.5*(prevVol+scene->cell->getVolume()):scene->cell->getVolume());
 			Real dW=-(scene->cell->gradV*midStress).trace()*scene->dt*midVol;
 			scene->energy->add(dW,"gradV",gradVIx,EnergyTracker::IsIncrement | EnergyTracker::ZeroDontCreate);
 		}
--- a/pkg/dem/Conveyor.cpp
+++ b/pkg/dem/Conveyor.cpp
@@ -34,7 +34,7 @@
 		for(const Real& r: radii) rMin=min(rMin,r);
 	}
 	// compute critDt from rMin
-	if(isinf(rMin)){
+	if(std::isinf(rMin)){
 		LOG_WARN("Minimum radius is infinite?!")
 		return Inf;
 	}
@@ -59,7 +59,7 @@
 				for(const auto& s: spherePack->pack){ centers.push_back(s.c); radii.push_back(s.r); }
 			}
 			if(spherePack->cellSize[0]>0) cellLen=spherePack->cellSize[0];
-			else if(isnan(cellLen)) throw std::runtime_error("ConveyorInlet: spherePack.cellSize[0]="+to_string(spherePack->cellSize[0])+": must be positive, or cellLen must be given.");
+			else if(std::isnan(cellLen)) throw std::runtime_error("ConveyorInlet: spherePack.cellSize[0]="+to_string(spherePack->cellSize[0])+": must be positive, or cellLen must be given.");
 			spherePack.reset();
 		}
 		// handles the case of clumps generated in the above block as well
@@ -121,8 +121,8 @@
 	if(vel<packVel && attr==&vel) throw std::runtime_error("ConveyorInlet: vel="+to_string(vel)+" m/s < "+to_string(packVel)+" m/s - minimum to achieve desired massRate="+to_string(massRate));
 	// otherwise show the massRate error instead (very small tolerance as FP might not get it right)
 	if(massRate>maxRate*(1+1e-6)) throw std::runtime_error("ConveyorInlet: massRate="+to_string(massRate)+" kg/s > "+to_string(maxRate)+" - maximum to achieve desired vel="+to_string(vel)+" m/s");
-	if(isnan(massRate)) massRate=maxRate;
-	if(isnan(vel)) vel=packVel;
+	if(std::isnan(massRate)) massRate=maxRate;
+	if(std::isnan(vel)) vel=packVel;
 	LOG_INFO("packVel="<<packVel<<"m/s, vel="<<vel<<"m/s, massRate="<<massRate<<"kg/s, maxRate="<<maxRate<<"kg/s; dilution factor "<<massRate/maxRate);
 
 
@@ -177,10 +177,10 @@
 void ConveyorInlet::nodeLeavesBarrier(const shared_ptr<Node>& n){
 	auto& dyn=n->getData<DemData>();
 	dyn.setBlockedNone();
-	Real c=isnan(color)?Mathr::UnitRandom():color;
+	Real c=std::isnan(color)?Mathr::UnitRandom():color;
 	setAttachedParticlesColor(n,c);
 	// assign velocity with randomized lateral components
-	if(!isnan(relLatVel) && relLatVel!=0){
+	if(!std::isnan(relLatVel) && relLatVel!=0){
 		dyn.vel=node->ori*(Vector3r(vel,(2*Mathr::UnitRandom()-1)*relLatVel*vel,(2*Mathr::UnitRandom()-1)*relLatVel*vel));
 		static bool warnedEnergyIgnored=false;
 		if(scene->trackEnergy && !warnedEnergyIgnored){
@@ -224,12 +224,12 @@
 void ConveyorInlet::run(){
 	DemField* dem=static_cast<DemField*>(field.get());
 	if(radii.empty() || radii.size()!=centers.size()) ValueError("ConveyorInlet: radii and centers must be same-length and non-empty (if shapePack is given, radii and centers should have been populated automatically)");
-	if(isnan(vel) || isnan(massRate) || !material) ValueError("ConveyorInlet: vel, massRate, material must be given.");
+	if(std::isnan(vel) || std::isnan(massRate) || !material) ValueError("ConveyorInlet: vel, massRate, material must be given.");
 	if(clipX.size()!=clipZ.size()) ValueError("ConveyorInlet: clipX and clipZ must have the same size ("+to_string(clipX.size())+"!="+to_string(clipZ.size()));
 	if(barrierLayer<0){
 		Real maxRad=-Inf;
 		for(const Real& r:radii) maxRad=max(r,maxRad);
-		if(isinf(maxRad)) throw std::logic_error("ConveyorInlet.radii: infinite value?");
+		if(std::isinf(maxRad)) throw std::logic_error("ConveyorInlet.radii: infinite value?");
 		barrierLayer=maxRad*abs(barrierLayer);
 		LOG_INFO("Setting barrierLayer="<<barrierLayer);
 	}
@@ -247,10 +247,10 @@
 	Real lenToDo;
 	if(stepPrev<0){ // first time run
 		if(startLen<=0) ValueError("ConveyorInlet.startLen must be positive or NaN (not "+to_string(startLen)+")");
-		if(!isnan(startLen)) lenToDo=startLen;
+		if(!std::isnan(startLen)) lenToDo=startLen;
 		else lenToDo=(stepPeriod>0?stepPeriod*scene->dt*packVel:scene->dt*packVel);
 	} else {
-		if(!isnan(virtPrev)) lenToDo=(scene->time-virtPrev)*packVel; // time elapsed since last run
+		if(!std::isnan(virtPrev)) lenToDo=(scene->time-virtPrev)*packVel; // time elapsed since last run
 		else lenToDo=scene->dt*packVel*(stepPeriod>0?stepPeriod:1);
 	}
 	Real stepMass=0;
@@ -265,7 +265,7 @@
 		Real nextX=centers[nextIx][0];
 		Real dX=lastX-nextX+((lastX<nextX && (nextIx==(int)centers.size()-1))?cellLen:0); // when wrapping, fix the difference
 		LOG_DEBUG("len toDo/done "<<lenToDo<<"/"<<lenDone<<", lastX="<<lastX<<", nextX="<<nextX<<", dX="<<dX<<", nextIx="<<nextIx);
-		if(isnan(abs(dX)) || isnan(abs(nextX)) || isnan(abs(lenDone)) || isnan(abs(lenToDo))) std::logic_error("ConveyorInlet: some parameters are NaN.");
+		if(std::isnan(abs(dX)) || std::isnan(abs(nextX)) || std::isnan(abs(lenDone)) || std::isnan(abs(lenToDo))) std::logic_error("ConveyorInlet: some parameters are NaN.");
 		if(lenDone+dX>lenToDo){
 			// the next sphere would not fit
 			lastX=CompUtils::wrapNum(lastX-(lenToDo-lenDone),cellLen); // put lastX before the next sphere
@@ -324,11 +324,11 @@
 		for(const auto& n: nn){
 			auto& dyn=n->getData<DemData>();
 			if(realSphereX<barrierLayer){
-				setAttachedParticlesColor(n,isnan(barrierColor)?Mathr::UnitRandom():barrierColor);
+				setAttachedParticlesColor(n,std::isnan(barrierColor)?Mathr::UnitRandom():barrierColor);
 				barrier.push_back(n);
 				dyn.setBlockedAll();
 			} else {
-				setAttachedParticlesColor(n,isnan(color)?Mathr::UnitRandom():color);
+				setAttachedParticlesColor(n,std::isnan(color)?Mathr::UnitRandom():color);
 			}
 
 			// set velocity;
@@ -383,7 +383,7 @@
 
 py::object ConveyorInlet::pyPsd(bool mass, bool cumulative, bool normalize, const Vector2r& dRange, const Vector2r& tRange, int num) const {
 	if(!save) throw std::runtime_error("ConveyorInlet.save must be True for calling ConveyorInlet.psd()");
-	auto tOk=[&tRange](const Real& t){ return isnan(tRange.minCoeff()) || (tRange[0]<=t && t<tRange[1]); };
+	auto tOk=[&tRange](const Real& t){ return std::isnan(tRange.minCoeff()) || (tRange[0]<=t && t<tRange[1]); };
 	vector<Vector2r> psd=DemFuncs::psd(genDiamMassTime,/*cumulative*/cumulative,/*normalize*/normalize,num,dRange,
 		/*radius getter*/[&tOk](const Vector3r& dmt) ->Real { return tOk(dmt[2])?dmt[0]:NaN; },
 		/*weight getter*/[&](const Vector3r& dmt) -> Real{ return mass?dmt[1]:1.; }
--- a/pkg/dem/DynDt.cpp
+++ b/pkg/dem/DynDt.cpp
@@ -64,8 +64,8 @@
 	for(const auto& n: field->cast<DemField>().nodes){
 		ret=min(ret,nodalCritDtSq(n));
 		if(ret==0){ LOG_ERROR("DynDt::nodalCriDtSq returning 0 for node at "<<n->pos<<"??"); }
-		if(isnan(ret)){ LOG_ERROR("DynDt::nodalCritDtSq returning nan for node at "<<n->pos<<"??"); }
-		assert(!isnan(ret));
+		if(std::isnan(ret)){ LOG_ERROR("DynDt::nodalCritDtSq returning nan for node at "<<n->pos<<"??"); }
+		assert(!std::isnan(ret));
 	}
 	return sqrt(ret);
 }
@@ -92,7 +92,7 @@
 	// prevent too fast changes, so cap the value with maxRelInc
 	Real crDt=critDt_compute();
 
-	if(isinf(crDt)){
+	if(std::isinf(crDt)){
 		if(!dryRun) LOG_INFO("No timestep computed, keeping the current value "<<scene->dt);
 		return;
 	}
--- a/pkg/dem/Facet.cpp
+++ b/pkg/dem/Facet.cpp
@@ -165,8 +165,8 @@
 	else {
 		// add fake velocity, unless the first component is NaN
 		// which ignores fakeVel and reset in-plane velocities
-		if(!isnan(fakeVel[0])) return std::make_tuple(linVel+fakeVel,angVel);
-		// with isnan(fakeVel[0]), zero out in-plane components
+		if(!std::isnan(fakeVel[0])) return std::make_tuple(linVel+fakeVel,angVel);
+		// with std::isnan(fakeVel[0]), zero out in-plane components
 		Vector3r fNormal=getNormal();
 		linVel=linVel.dot(fNormal)*fNormal; 
 		return std::make_tuple(linVel,angVel);
@@ -279,7 +279,7 @@
 	Vector3r linVel,angVel;
 	std::tie(linVel,angVel)=f.interpolatePtLinAngVel(contPt);
 	#ifdef CATCH_NAN_FACET_SPHERE
-		if(isnan(linVel[0])||isnan(linVel[1])||isnan(linVel[2])||isnan(angVel[0])||isnan(angVel[1])||isnan(angVel[2])) LOG_FATAL("NaN in interpolated facet velocity: linVel="<<linVel.transpose()<<", angVel="<<angVel.transpose()<<", contPt="<<contPt.transpose()<<"; particles Facet #"<<C->leakPA()->id<<" @ "<<f.nodes[0]->pos.transpose()<<", "<<f.nodes[1]->pos.transpose()<<", "<<f.nodes[2]->pos.transpose()<<" and Sphere #"<<C->leakPB()->id<<" @ "<<s.nodes[0]->pos.transpose()<<", r="<<s.radius)
+		if(std::isnan(linVel[0])||std::isnan(linVel[1])||std::isnan(linVel[2])||std::isnan(angVel[0])||std::isnan(angVel[1])||std::isnan(angVel[2])) LOG_FATAL("NaN in interpolated facet velocity: linVel="<<linVel.transpose()<<", angVel="<<angVel.transpose()<<", contPt="<<contPt.transpose()<<"; particles Facet #"<<C->leakPA()->id<<" @ "<<f.nodes[0]->pos.transpose()<<", "<<f.nodes[1]->pos.transpose()<<", "<<f.nodes[2]->pos.transpose()<<" and Sphere #"<<C->leakPB()->id<<" @ "<<s.nodes[0]->pos.transpose()<<", r="<<s.radius)
 	#endif
 	const DemData& dyn2(s.nodes[0]->getData<DemData>()); // sphere
 	// check if this will work when contact point == pseudo-position of the facet
@@ -373,7 +373,7 @@
 	Vector3r ptA, ptB, contPt, normal;
 	Real uN;
 
-	if(close.empty () && must && isinf(minD2)) throw std::logic_error("Cf2_Facet_Facet_L6GeomL: minD2==Inf but the contact must be computed!");
+	if(close.empty () && must && std::isinf(minD2)) throw std::logic_error("Cf2_Facet_Facet_L6GeomL: minD2==Inf but the contact must be computed!");
 	if(close.empty()){
 		// use the closest point
 		ptA=minPts.head<3>(); ptB=minPts.tail<3>();
@@ -488,7 +488,7 @@
 		glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
 		glLineWidth(1);
 	}
-	if(!isnan(color[0]))	glColor3v(color);
+	if(!std::isnan(color[0]))	glColor3v(color);
 	Real len=(B-A).norm();
 	Vector3r axis=(B-A)/len;
 	Matrix3r T; T.col(0)=axis; T.col(1)=upVec.cross(axis); T.col(2)=upVec;
--- a/pkg/dem/FlowAnalysis.cpp
+++ b/pkg/dem/FlowAnalysis.cpp
@@ -110,7 +110,7 @@
 		pt[PT_SUM_WEIGHT]+=w*1.;
 		pt[PT_SUM_DIAM]+=w*diameter; // the average is computed later, dividing by PT_SUM_WEIGHT
 		pt[PT_SUM_PORO]+=w*(M_PI*pow(diameter,3)/6.)/V;
-		assert(!isnan(pt[PT_FLOW_X]) && !isnan(pt[PT_FLOW_Y]) && !isnan(pt[PT_FLOW_Z]) && !isnan(pt[PT_EK]) && !isnan(pt[PT_SUM_WEIGHT]));
+		assert(!std::isnan(pt[PT_FLOW_X]) && !std::isnan(pt[PT_FLOW_Y]) && !std::isnan(pt[PT_FLOW_Z]) && !std::isnan(pt[PT_EK]) && !std::isnan(pt[PT_SUM_WEIGHT]));
 	}
 };
 
@@ -121,7 +121,7 @@
 		if(mask!=0 && (p->mask&mask)==0) continue;
 		//if(!p->shape->isA<Sphere>()) continue;
 		Real radius=p->shape->equivRadius();
-		if(isnan(radius)) continue;
+		if(std::isnan(radius)) continue;
 		if(!enlargedBox.contains(p->shape->nodes[0]->pos)) continue;
 		addOneParticle(radius*2.,p->mask,p->shape->nodes[0]);
 	}
@@ -287,7 +287,7 @@
 	for(size_t i=0; i<fracB.size(); i++) if((int)fracB[i]>=nFractions) throw std::runtime_error("FlowAnalysis.vtkExportVectorOps: fracB["+to_string(i)+"]="+to_string(fracB[i])+" out of range 0.."+to_string(nFractions-1));
 
 	Real weightB=avgFlowNorm(fracA)/avgFlowNorm(fracB);
-	if(isnan(weightB)){
+	if(std::isnan(weightB)){
 		LOG_WARN("Weighting coefficient is NaN (no flow in fraction B), using 1 instead; the result will be still mathematically correct but useless.")
 		weightB=1.;
 	}
--- a/pkg/dem/Funcs.cpp
+++ b/pkg/dem/Funcs.cpp
@@ -106,7 +106,7 @@
 	for(Real q: quantiles){
 		// clamp the value to 0,1
 		q=min(max(0.,q),1.);
-		if(isnan(q)) q=0.; // just to make sure
+		if(std::isnan(q)) q=0.; // just to make sure
 		int i=min((int)((N-1)*q),(int)N-1);
 		ret.push_back(coords[i]);
 	}
@@ -252,7 +252,7 @@
 		if(s.clumpId>=0) throw std::runtime_error("Clumps not supported.");
 		shared_ptr<Particle> p=makeSphere(s.r,mat);
 		p->shape->nodes[0]->pos=s.c;
-		p->shape->color=(!isnan(color)?color:Mathr::UnitRandom());
+		p->shape->color=(!std::isnan(color)?color:Mathr::UnitRandom());
 		p->mask=mask;
 		ret.push_back(dem->particles->insert(p));
 	}
@@ -261,7 +261,7 @@
 
 
 vector<Vector2r> DemFuncs::boxPsd(const Scene* scene, const DemField* dem, const AlignedBox3r& box, bool mass, int num, int mask, Vector2r rRange){
-	bool haveBox=!isnan(box.min()[0]) && !isnan(box.max()[0]);
+	bool haveBox=!std::isnan(box.min()[0]) && !std::isnan(box.max()[0]);
 	return psd(
 		*dem->particles|boost::adaptors::filtered([&](const shared_ptr<Particle>&p){ return p && p->shape && p->shape->nodes.size()==1 && (mask?(p->mask&mask):true) && (bool)(dynamic_pointer_cast<woo::Sphere>(p->shape)) && (haveBox?box.contains(p->shape->nodes[0]->pos):true); }),
 		/*cumulative*/true,/*normalize*/true,
@@ -572,7 +572,7 @@
 		const auto& trace=n->rep->cast<TraceVisRep>();
 		if(!p || !p->shape) continue;
 		Real r=p->shape->equivRadius();
-		if(isnan(r)) continue; // skip non-spheroids
+		if(std::isnan(r)) continue; // skip non-spheroids
 		size_t count=trace.countPointData();
 		if(count<=1) continue;
 		// radius
--- a/pkg/dem/G3Geom.cpp
+++ b/pkg/dem/G3Geom.cpp
@@ -7,7 +7,7 @@
 WOO_PLUGIN(dem,(G3Geom)(Cg2_Sphere_Sphere_G3Geom)(Cg2_Wall_Sphere_G3Geom)(Law2_G3Geom_FrictPhys_IdealElPl)(G3GeomCData));
 
 void G3Geom::rotateVectorWithContact(Vector3r& v){
-	assert(!isnan(orthonormalAxis.maxCoeff()) && !isnan(twistAxis.maxCoeff()));
+	assert(!std::isnan(orthonormalAxis.maxCoeff()) && !std::isnan(twistAxis.maxCoeff()));
 	v-=v.cross(orthonormalAxis);
 	v-=v.cross(twistAxis);
 	// v-=normal.dot(v)*normal;
--- a/pkg/dem/Gl1_CPhys.cpp
+++ b/pkg/dem/Gl1_CPhys.cpp
@@ -22,11 +22,11 @@
 	if(shearColor && !shearRange) shearColor=false;
 	// shared_ptr<CGeom> cg(C->geom); if(!cg) return; // changed meanwhile?
 	Real fn=cp->force[0];
-	if(isnan(fn)) return;
+	if(std::isnan(fn)) return;
 	if((signFilter>0 && fn<0) || (signFilter<0 && fn>0)) return;
 	range->norm(fn); // adjust range, return value discarded
 	Real r=relMaxRad*viewInfo.sceneRadius*min(1.,(abs(fn)/(max(abs(range->mnmx[0]),abs(range->mnmx[1])))));
-	if(r<viewInfo.sceneRadius*1e-4 || isnan(r)) return;
+	if(r<viewInfo.sceneRadius*1e-4 || std::isnan(r)) return;
 	Vector3r color=shearColor?shearRange->color(Vector2r(cp->force[1],cp->force[2]).norm()):range->color(fn);
 	const Particle *pA=C->leakPA(), *pB=C->leakPB();
 	// get both particle's space positions, but B moved so that it is relative to A as the contact is
--- a/pkg/dem/Gl1_DemField.cpp
+++ b/pkg/dem/Gl1_DemField.cpp
@@ -221,7 +221,7 @@
 		if(!sh->getVisible() || clipped) continue;
 
 		bool useColor2=false;
-		bool isSpheroid(!isnan(p->shape->equivRadius()));
+		bool isSpheroid(!std::isnan(p->shape->equivRadius()));
 		Real radius=p->shape->equivRadius();
 		if(dyn0.isClump()) radius=dyn0.cast<ClumpData>().equivRad;
 
@@ -235,7 +235,7 @@
 		}
 		// additional conditions under which colorBy2 is used
 		if(false
-			|| (colorBy==COLOR_RADIUS && isnan(radius))
+			|| (colorBy==COLOR_RADIUS && std::isnan(radius))
 			|| (colorBy==COLOR_MATSTATE && !p->matState)
 			/* || (!isSpheroid && (colorBy==COLOR_SIG_N || colorBy==COLOR_SIG_T)) */
 		) useColor2=true;
@@ -262,7 +262,7 @@
 		};
 		int cBy=(!useColor2?colorBy:colorBy2);
 		switch(cBy){
-			case COLOR_RADIUS: parColor=(!isnan(radius)?CR->color(radius):(solidColor)); break;
+			case COLOR_RADIUS: parColor=(!std::isnan(radius)?CR->color(radius):(solidColor)); break;
 			case COLOR_VEL: parColor=CR->color(vecNormXyz(getParticleVel(p))); break;
 			case COLOR_ANGVEL: parColor=CR->color(vecNormXyz(getNodeAngVel(n0))); break;
 			case COLOR_MASS: parColor=CR->color(dyn0.mass); break;
@@ -277,7 +277,7 @@
 			case COLOR_MATSTATE:{
 				if(CR->label.empty() && p->matState) CR->label=p->matState->getScalarName(matStateIx);
 				Real sc=(p->matState?p->matState->getScalar(matStateIx,scene->step,matStateSmooth):NaN);
-				parColor=isnan(sc)?solidColor:CR->color(sc);
+				parColor=std::isnan(sc)?solidColor:CR->color(sc);
 				break;
 			}
 			case COLOR_SHAPE: parColor=CR->color(p->shape->getBaseColor()); break;
@@ -335,7 +335,7 @@
 			// this will not work with sheared cell, but we don't support that with inifinite bounds anyway
 			for(int ax:{0,1,2}){
 				const auto& cellDim(scene->cell->getHSize().diagonal());
-				if(isinf(sh->bound->min[ax]) || isinf(sh->bound->max[ax])){
+				if(std::isinf(sh->bound->min[ax]) || std::isinf(sh->bound->max[ax])){
 					pos[ax]=halfSize[ax]=.5*cellDim[ax];
 				}
 			}
--- a/pkg/dem/Hertz.cpp
+++ b/pkg/dem/Hertz.cpp
@@ -133,7 +133,7 @@
 		ph.contRad=a;
 		Real Pne=pow(sqrt(pow(a,3)*(K/R))-alpha*sqrt(-Pc),2)+Pc;
 		Fne=-Pne; // inverse convention
-		if(isnan(Pne)){
+		if(std::isnan(Pne)){
 			cerr<<"R="<<R<<", K="<<K<<", xi="<<xi<<", alpha="<<alpha<<endl;
 			cerr<<"delta="<<delta<<", deltaMin="<<deltaMin<<", aMin="<<aMin<<", aLo="<<aLo<<", aHi="<<aHi<<", a="<<a<<", iter="<<iter<<", Pne="<<Pne<<"; \n\n";
 			abort();
@@ -170,7 +170,7 @@
 		Ft+=eta*velT;
 		if(unlikely(scene->trackEnergy)) scene->energy->add(eta*velT.dot(velT)*dt,"viscT",viscTIx,EnergyTracker::IsIncrement|EnergyTracker::ZeroDontCreate);
 	}
-	assert(!isnan(Fn)); assert(!isnan(Ft[0]) && !isnan(Ft[1]));
+	assert(!std::isnan(Fn)); assert(!std::isnan(Ft[0]) && !std::isnan(Ft[1]));
 	// elastic potential energy
 	if(unlikely(scene->trackEnergy)){
 		// XXX: this is incorrect with adhesion
--- a/pkg/dem/IdealElPl.cpp
+++ b/pkg/dem/IdealElPl.cpp
@@ -73,7 +73,7 @@
 			Ft*=ratio;
 			_WATCH_MSG("\tPlastic slip by "<<((Ft/ratio)*(1-ratio)).transpose()<<", ratio="<<ratio<<", new Ft="<<Ft.transpose()<<endl);
 		}
-		if(isnan(ph.force.maxCoeff())){
+		if(std::isnan(ph.force.maxCoeff())){
 			LOG_FATAL("##"<<C->leakPA()->id<<"+"<<C->leakPB()->id<<" ("<<C->leakPA()->shape->getClassName()<<"+"<<C->leakPB()->shape->getClassName()<<") has NaN force!");
 			LOG_FATAL("    uN="<<uN<<", velT="<<velT.transpose()<<", F="<<ph.force.transpose()<<"; maxFt="<<maxFt<<"; kn="<<ph.kn<<", kt="<<ph.kt);
 			throw std::runtime_error("NaN force in contact (message above)?!");
@@ -81,7 +81,7 @@
 	}
 	if(unlikely(scene->trackEnergy)){
 		Real elast=0.5*(pow(ph.force[0],2)/ph.kn+(ph.kt!=0.?Ft.squaredNorm()/ph.kt:0.));
-		if(isnan(elast)){
+		if(std::isnan(elast)){
 			LOG_WARN("elast==NaN: Fn="<<ph.force[0]<<", kn="<<ph.kn<<", Ft=("<<Ft[0]<<","<<Ft[1]<<"), kt="<<ph.kt);
 			elast=0.; // this should not happen...?!
 		}
@@ -113,7 +113,7 @@
 			// TODO: dissipation
 			Tr*=ratio;
 		};
-		if(isnan(ph.torque.maxCoeff())) LOG_ERROR("NaN in torque in "+C->pyStr());
+		if(std::isnan(ph.torque.maxCoeff())) LOG_ERROR("NaN in torque in "+C->pyStr());
 	} else {
 		// in case we disable rolling&twisting during the simulation
 		ph.torque=Vector3r::Zero();
--- a/pkg/dem/InfCylinder.cpp
+++ b/pkg/dem/InfCylinder.cpp
@@ -92,7 +92,7 @@
 			A[ax]=-.5*hSize[ax];
 			B[ax]=+.5*hSize[ax];
 		}
-		else if(isnan(cyl.glAB.maxCoeff())){
+		else if(std::isnan(cyl.glAB.maxCoeff())){
 			Vector3r mid=cyl.nodes[0]->pos; mid[ax]=viewInfo.sceneCenter[ax];
 			GLUtils::setLocalCoords(mid,cyl.nodes[0]->ori);
 			A[ax]=-viewInfo.sceneRadius;
--- a/pkg/dem/Inlet.cpp
+++ b/pkg/dem/Inlet.cpp
@@ -145,7 +145,7 @@
 	void Inlet::renderMassAndRate(const Vector3r& pos){
 		std::ostringstream oss; oss.precision(4); oss<<mass;
 		if(maxMass>0){ oss<<"/"; oss.precision(4); oss<<maxMass; }
-		if(!isnan(currRate) && !isinf(currRate)){ oss.precision(3); oss<<"\n("<<currRate<<")"; }
+		if(!std::isnan(currRate) && !std::isinf(currRate)){ oss.precision(3); oss<<"\n("<<currRate<<")"; }
 		GLUtils::GLDrawText(oss.str(),pos,CompUtils::mapColor(glColor));
 	}
 #endif
@@ -153,7 +153,7 @@
 
 py::object ParticleGenerator::pyPsd(bool mass, bool cumulative, bool normalize, const Vector2r& dRange, const Vector2r& tRange, int num) const {
 	if(!save) throw std::runtime_error("ParticleGenerator.save must be True for calling ParticleGenerator.psd()");
-	auto tOk=[&tRange](const Real& t){ return isnan(tRange.minCoeff()) || (tRange[0]<=t && t<tRange[1]); };
+	auto tOk=[&tRange](const Real& t){ return std::isnan(tRange.minCoeff()) || (tRange[0]<=t && t<tRange[1]); };
 	vector<Vector2r> psd=DemFuncs::psd(genDiamMassTime,/*cumulative*/cumulative,/*normalize*/normalize,num,dRange,
 		/*diameter getter*/[&tOk](const Vector3r& dmt) ->Real { return tOk(dmt[2])?dmt[0]:NaN; },
 		/*weight getter*/[&](const Vector3r& dmt) -> Real{ return mass?dmt[1]:1.; }
@@ -177,7 +177,7 @@
 
 std::tuple<Real,vector<ParticleGenerator::ParticleAndBox>>
 MinMaxSphereGenerator::operator()(const shared_ptr<Material>&mat, const Real& time){
-	if(isnan(dRange[0]) || isnan(dRange[1]) || dRange[0]>dRange[1]) throw std::runtime_error("MinMaxSphereGenerator: dRange[0]>dRange[1], or they are NaN!");
+	if(std::isnan(dRange[0]) || std::isnan(dRange[1]) || dRange[0]>dRange[1]) throw std::runtime_error("MinMaxSphereGenerator: dRange[0]>dRange[1], or they are NaN!");
 	Real r=.5*(dRange[0]+Mathr::UnitRandom()*(dRange[1]-dRange[0]));
 	auto sphere=DemFuncs::makeSphere(r,mat);
 	Real m=sphere->shape->nodes[0]->getData<DemData>().mass;
@@ -225,14 +225,14 @@
 		}
 		if(dynamic_pointer_cast<InsertionSortCollider>(collider)) static_pointer_cast<InsertionSortCollider>(collider)->forceInitSort=true;
 	}
-	if(isnan(massRate)) throw std::runtime_error("RandomInlet.massRate must be given (is "+to_string(massRate)+"); if you want to generate as many particles as possible, say massRate=0.");
+	if(std::isnan(massRate)) throw std::runtime_error("RandomInlet.massRate must be given (is "+to_string(massRate)+"); if you want to generate as many particles as possible, say massRate=0.");
 	if(massRate<=0 && maxAttempts==0) throw std::runtime_error("RandomInlet.massFlowRate<=0 (no massFlowRate prescribed), but RandomInlet.maxAttempts==0. (unlimited number of attempts); this would cause infinite loop.");
 	if(maxAttempts<0){
 		std::runtime_error("RandomInlet.maxAttempts must be non-negative. Negative value, leading to meaking engine dead, is achieved by setting atMaxAttempts=RandomInlet.maxAttDead now.");
 	}
 	spheresOnly=generator->isSpheresOnly();
 	padDist=generator->padDist();
-	if(isnan(padDist) || padDist<0) throw std::runtime_error(generator->pyStr()+".padDist(): returned invalid value "+to_string(padDist));
+	if(std::isnan(padDist) || padDist<0) throw std::runtime_error(generator->pyStr()+".padDist(): returned invalid value "+to_string(padDist));
 
 	// as if some time has already elapsed at the very start
 	// otherwise mass flow rate is too big since one particle during Δt exceeds it easily
@@ -381,7 +381,7 @@
 		num+=1;
 
 		#ifdef WOO_OPENGL			
-			Real color_=isnan(color)?Mathr::UnitRandom():color;
+			Real color_=std::isnan(color)?Mathr::UnitRandom():color;
 		#endif
 		if(pee.size()>1){ // clump was generated
 			//LOG_WARN("Clumps not yet tested properly.");
@@ -486,7 +486,7 @@
 
 #ifdef WOO_OPENGL
 	void CylinderInlet::render(const GLViewInfo&){
-		if(isnan(glColor) || !node) return;
+		if(std::isnan(glColor) || !node) return;
 		GLUtils::Cylinder(node->loc2glob(Vector3r::Zero()),node->loc2glob(Vector3r(height,0,0)),radius,CompUtils::mapColor(glColor),/*wire*/true,/*caps*/false,/*rad2: use rad1*/-1,/*slices*/glSlices);
 		Inlet::renderMassAndRate(node->loc2glob(Vector3r(height/2,0,0)));
 	}
@@ -546,7 +546,7 @@
 
 #ifdef WOO_OPENGL
 	void ArcInlet::render(const GLViewInfo&) {
-		if(isnan(glColor)) return;
+		if(std::isnan(glColor)) return;
 		glPushMatrix();
 			GLUtils::setLocalCoords(node->pos,node->ori);
 			GLUtils::RevolvedRectangle(cylBox,CompUtils::mapColor(glColor),glSlices);
--- a/pkg/dem/InsertionSortCollider.cpp
+++ b/pkg/dem/InsertionSortCollider.cpp
@@ -294,7 +294,7 @@
 			if(!p->shape->isA<Sphere>())continue;
 			minR=min(p->shape->cast<Sphere>().radius,minR);
 		}
-		verletDist=isinf(minR) ? 0 : abs(verletDist)*minR;
+		verletDist=std::isinf(minR) ? 0 : abs(verletDist)*minR;
 	}
 
 	bool recomputeBounds=false;
@@ -315,11 +315,11 @@
 			// existing bound, do we need to update it?
 			const Aabb& aabb=p->shape->bound->cast<Aabb>();
 			assert(aabb.nodeLastPos.size()==p->shape->nodes.size());
-			if(isnan(aabb.min.maxCoeff())||isnan(aabb.max.maxCoeff())) { recomputeBounds=true; break; } 
+			if(std::isnan(aabb.min.maxCoeff())||std::isnan(aabb.max.maxCoeff())) { recomputeBounds=true; break; } 
 			// check rotation difference, for particles where it matters
 			Real moveDueToRot2=0.;
 			if(aabb.maxRot>=0.){
-				assert(!isnan(aabb.maxRot));
+				assert(!std::isnan(aabb.maxRot));
 				Real maxRot=0.;
 				for(int i=0; i<nNodes; i++){
 					AngleAxisr aa(aabb.nodeLastOri[i].conjugate()*p->shape->nodes[i]->ori);
@@ -393,7 +393,7 @@
 			aabb.nodeLastOri[i]=p->shape->nodes[i]->ori;
 		}
 		aabb.maxD2=pow(verletDist,2);
-		if(isnan(aabb.maxRot)) throw std::runtime_error("S.dem.par["+to_string(p->id)+"]: bound functor did not set maxRot -- should be set to either to a negative value (to ignore it) or to non-negative value (maxRot will be set from verletDist in that case); this is an implementation error.");
+		if(std::isnan(aabb.maxRot)) throw std::runtime_error("S.dem.par["+to_string(p->id)+"]: bound functor did not set maxRot -- should be set to either to a negative value (to ignore it) or to non-negative value (maxRot will be set from verletDist in that case); this is an implementation error.");
 		#if 0
 			// proportionally to relVel, shift bbox margin in the direction of velocity
 			// take velocity of nodes[0] as representative
@@ -524,9 +524,9 @@
 					// watch out for the parentheses around ?: within ?: (there was unwanted conversion of the Reals to bools!)
 					BBj[i].coord=((BBj[i].flags.hasBB=((bool)bv)) ? (BBj[i].flags.isMin ? bv->min[j] : bv->max[j]) : (b->shape->nodes[0]->pos[j])) - (periodic ? BBj.cellDim*BBj[i].period : 0.);
 					BBj[i].flags.isInf=false;
-					if(periodic && isinf(BBj[i].coord)){
+					if(periodic && std::isinf(BBj[i].coord)){
 						// check that min and max are both infinite or none of them
-						assert(!bv || ((isinf(bv->min[j]) && isinf(bv->max[j])) || (!isinf(bv->min[j]) && !isinf(bv->max[j]))));
+						assert(!bv || ((std::isinf(bv->min[j]) && std::isinf(bv->max[j])) || (!std::isinf(bv->min[j]) && !std::isinf(bv->max[j]))));
 						// infinite particles span between cell boundaries, the lower bound having period 0, the upper one 1 (this should not change)
 						BBj[i].period=(BBj[i].coord<0?0:1); BBj[i].coord=0.; /* wasInf=true; */
 						BBj[i].flags.isInf=true; // keep track of infinite coord here, so that we know there is no separation possible later
@@ -908,16 +908,16 @@
 		{
 			// assertions; guard in block to avoid name clash with vars below
 			__attribute__((unused)) const Real &mn1(minima[3*id1+axis]), &mx1(maxima[3*id1+axis]), &mn2(minima[3*id2+axis]), &mx2(maxima[3*id2+axis]);
-			assert(!isnan(mn1)); assert(!isnan(mx1));
-			assert(!isnan(mn2)); assert(!isnan(mx2));
-			assert(isinf(mx1) || (mx1-mn1<.99*dim)); assert(isinf(mx2) || (mx2-mn2<.99*dim));
+			assert(!std::isnan(mn1)); assert(!std::isnan(mx1));
+			assert(!std::isnan(mn2)); assert(!std::isnan(mx2));
+			assert(std::isinf(mx1) || (mx1-mn1<.99*dim)); assert(std::isinf(mx2) || (mx2-mn2<.99*dim));
 		}
 		// find particle of which minimum when taken as period start will make the gap smaller
 		Real m1=minima[3*id1+axis],m2=minima[3*id2+axis];
 		// infinite particles always overlap, cut it short
-		if(isinf(m1) || isinf(m2)){
-			assert(!isinf(m1) || m1<0); // check that minimum is minus infinity
-			assert(!isinf(m2) || m2<0); // check that minimum is minus infinity
+		if(std::isinf(m1) || std::isinf(m2)){
+			assert(!std::isinf(m1) || m1<0); // check that minimum is minus infinity
+			assert(!std::isinf(m2) || m2<0); // check that minimum is minus infinity
 			periods[axis]=0; // does not matter where the contact happens really
 			#ifdef PISC_DEBUG
 				if(watchIds(id1,id2)){ LOG_DEBUG("    Some particle infinite along the "<<axis<<" axis."); }
--- a/pkg/dem/LawTester.cpp
+++ b/pkg/dem/LawTester.cpp
@@ -206,7 +206,7 @@
 			k<<Vector3r(ph.kn,ph.kt,ph.kt),Vector3r::Zero();
 		} else k=Vector6r::Constant(NaN);
 		stg->hasC=stg->hadC=true;
-		if(isnan(smooF[0])){ // the contact is new in this step (or we are new), just save unsmoothed value
+		if(std::isnan(smooF[0])){ // the contact is new in this step (or we are new), just save unsmoothed value
 			u=Vector6r::Zero(); u[0]=l6g->uN;
 			smooF=f; smooV=v; smooU=u;
 			fErrRel=fErrAbs=uErrRel=uErrAbs=vErrRel=vErrAbs=Vector6r::Constant(NaN);
@@ -216,7 +216,7 @@
 			// smooth all values here
 			#define _SMOO_ERR(foo,smooFoo,fooErrRel,fooErrAbs) smooFoo=(1-smooth)*smooFoo+smooth*foo; {\
 				Vector6r rErr=((foo.array()-smooFoo.array())/smooFoo.array()).abs().matrix(); Vector6r aErr=(foo.array()-smooFoo.array()).abs().matrix();\
-				if(isnan(fooErrRel[0])){ fooErrRel=rErr; fooErrAbs=aErr; } \
+				if(std::isnan(fooErrRel[0])){ fooErrRel=rErr; fooErrAbs=aErr; } \
 				else{ fooErrRel=(1-smoothErr)*fooErrRel+smoothErr*rErr; fooErrAbs=(1-smoothErr)*fooErrAbs+smoothErr*aErr; } \
 			}
 			_SMOO_ERR(f,smooF,fErrRel,fErrAbs);
--- a/pkg/dem/Leapfrog.cpp
+++ b/pkg/dem/Leapfrog.cpp
@@ -87,7 +87,7 @@
 		Matrix3r T(node->ori);
 		Erot=.5*currFluctAngVel.transpose().dot((T.transpose()*mI*T)*currFluctAngVel);
 	} else { Erot=0.5*currFluctAngVel.dot((dyn.inertia.array()*currFluctAngVel.array()).matrix()); }
-	if(isnan(Erot) || isinf(dyn.inertia.maxCoeff())) Erot=0;
+	if(std::isnan(Erot) || std::isinf(dyn.inertia.maxCoeff())) Erot=0;
 	if(!kinSplit) scene->energy->add(Etrans+Erot,"kinetic",kinEnergyIx,EnergyTracker::IsResettable);
 	else{
 		scene->energy->add(Etrans,"kinTrans",kinEnergyTransIx,EnergyTracker::IsResettable);
@@ -291,7 +291,7 @@
 	Quaternionr& ori(node->ori); DemData& dyn(node->getData<DemData>());
 	Vector3r& angMom(dyn.angMom);	Vector3r& angVel(dyn.angVel);	const Vector3r& inertia(dyn.inertia);
 	// initialize angular momentum; it is in local coordinates, therefore angVel must be rotated
-	if(isnan(angMom.minCoeff())){
+	if(std::isnan(angMom.minCoeff())){
 		angMom=dyn.inertia.asDiagonal()*node->ori.conjugate()*dyn.angVel;
 	}
 
--- a/pkg/dem/OpenCLCollider.cpp
+++ b/pkg/dem/OpenCLCollider.cpp
@@ -81,7 +81,7 @@
 	vector<Vector2i> ret;
 	LOG_TRACE("Initial sort, number of bounds "<<cpuBounds[0].size());
 	// sort all arrays without looking for inversions first
-	for(int ax:{0,1,2}) std::sort(cpuBounds[ax].begin(),cpuBounds[ax].end(),[](const CpuAxBound& b1, const CpuAxBound& b2) -> bool { return (isnan(b1.coord)||isnan(b2.coord))?true:(b1.coord<b2.coord)||(b1.coord==b2.coord&&b1.id<b2.id);} );
+	for(int ax:{0,1,2}) std::sort(cpuBounds[ax].begin(),cpuBounds[ax].end(),[](const CpuAxBound& b1, const CpuAxBound& b2) -> bool { return (std::isnan(b1.coord)||std::isnan(b2.coord))?true:(b1.coord<b2.coord)||(b1.coord==b2.coord&&b1.id<b2.id);} );
 	// traverse one axis, always from lower bound to upper bound of the same particle
 	// all intermediary bounds are candidates for collision, which must be checked in maxi/mini
 	// along other two axes
@@ -93,12 +93,12 @@
 	int ax0=0; // int ax1=(ax0+1)%3, ax2=(ax0+2)%3;
 	for(size_t i=0; i<cpuBounds[ax0].size(); i++){
 		const CpuAxBound& b(cpuBounds[ax0][i]);
-		if(!b.isMin || isnan(b.coord)) continue;
+		if(!b.isMin || std::isnan(b.coord)) continue;
 		LOG_TRACE("← "<<b.coord<<", #"<<b.id);
 		for(size_t j=i+1; cpuBounds[ax0][j].id!=b.id && /* just in case, e.g. maximum smaller than minimum */ j<cpuBounds[ax0].size(); j++){
 			numInvs++;
 			const CpuAxBound& b2(cpuBounds[ax0][j]);
-			if(!b2.isMin || isnan(b2.coord)) continue; // overlaps of this kind have been already checked when b2.id was processed upwards
+			if(!b2.isMin || std::isnan(b2.coord)) continue; // overlaps of this kind have been already checked when b2.id was processed upwards
 			LOG_TRACE("\t→ "<<b2.coord<<", #"<<b2.id);
 			if(!bboxOverlap(b.id,b2.id)){ LOG_TRACE("\t-- no overlap"); continue; } // when no overlap along all axes, stop
 			/* create new potential contact here */
@@ -119,12 +119,12 @@
 	for(long i=0; i<iMax; i++){
 	//	LOG_DEBUG(bb[i].coord);
 		const CpuAxBound bbInit=bb[i]; // copy, so that it is const
-		if(isnan(bbInit.coord)) continue;
+		if(std::isnan(bbInit.coord)) continue;
 		long j=i-1;
-		while(j>=0 && (bb[j].coord>bbInit.coord || isnan(bb[j].coord))){
+		while(j>=0 && (bb[j].coord>bbInit.coord || std::isnan(bb[j].coord))){
 			// bbInit is bb[j+1] which is travelling downwards and swaps with b[j]
 			// do not store min-min, max-max, nan inversions
-			if(bbInit.isMin!=bb[j].isMin && !isnan(bb[j].coord)){
+			if(bbInit.isMin!=bb[j].isMin && !std::isnan(bb[j].coord)){
 				int minId=min(bbInit.id,bb[j].id), maxId=max(bbInit.id,bb[j].id);
 				// min going below max
 				if(bbInit.isMin) inv.push_back(Vector2i(minId,maxId));
--- a/pkg/dem/Outlet.cpp
+++ b/pkg/dem/Outlet.cpp
@@ -103,7 +103,7 @@
 	// use the whole stepPeriod for the first time (might be residuum from previous packing), if specified
 	// otherwise the rate might be artificially high at the beginning
 	Real currRateNoSmooth=stepMass/((((stepPrev<0 && stepPeriod>0)?stepPeriod:scene->step-stepPrev))*scene->dt); 
-	if(isnan(currRate)||stepPrev<0) currRate=currRateNoSmooth;
+	if(std::isnan(currRate)||stepPrev<0) currRate=currRateNoSmooth;
 	else currRate=(1-currRateSmooth)*currRate+currRateSmooth*currRateNoSmooth;
 }
 py::object Outlet::pyDiamMass(bool zipped) const {
@@ -121,7 +121,7 @@
 
 py::object Outlet::pyPsd(bool _mass, bool cumulative, bool normalize, int _num, const Vector2r& dRange, const Vector2r& tRange, bool zip, bool emptyOk){
 	if(!save) throw std::runtime_error("Outlet.psd(): Outlet.save must be True.");
-	auto tOk=[&tRange](const Real& t){ return isnan(tRange.minCoeff()) || (tRange[0]<=t && t<tRange[1]); };
+	auto tOk=[&tRange](const Real& t){ return std::isnan(tRange.minCoeff()) || (tRange[0]<=t && t<tRange[1]); };
 	vector<Vector2r> psd=DemFuncs::psd(diamMassTime,cumulative,normalize,_num,dRange,
 		/*diameter getter*/[&tOk](const Vector3r& dmt)->Real{ return tOk(dmt[2])?dmt[0]:NaN; },
 		/*weight getter*/[&_mass](const Vector3r& dmt)->Real{ return _mass?dmt[1]:1.; },
@@ -133,10 +133,10 @@
 
 #ifdef WOO_OPENGL
 	void Outlet::renderMassAndRate(const Vector3r& pos){
-		if(glHideZero && (isnan(currRate) || currRate==0) && mass!=0) return;
+		if(glHideZero && (std::isnan(currRate) || currRate==0) && mass!=0) return;
 		std::ostringstream oss;
 		oss.precision(4); oss<<mass;
-		if(!isnan(currRate)){ oss.precision(3); oss<<"\n("<<currRate<<")"; }
+		if(!std::isnan(currRate)){ oss.precision(3); oss<<"\n("<<currRate<<")"; }
 		GLUtils::GLDrawText(oss.str(),pos,CompUtils::mapColor(glColor));
 	}
 #endif
@@ -144,7 +144,7 @@
 
 #ifdef WOO_OPENGL
 void BoxOutlet::render(const GLViewInfo&){
-	if(isnan(glColor)) return;
+	if(std::isnan(glColor)) return;
 	Vector3r center;
 	if(!node){
 		GLUtils::AlignedBox(box,CompUtils::mapColor(glColor));
@@ -168,7 +168,7 @@
 bool ArcOutlet::isInside(const Vector3r& p){ return CompUtils::cylCoordBox_contains_cartesian(cylBox,node->glob2loc(p)); }
 #ifdef WOO_OPENGL
 	void ArcOutlet::render(const GLViewInfo&){
-		if(isnan(glColor)) return;
+		if(std::isnan(glColor)) return;
 		glPushMatrix();
 			GLUtils::setLocalCoords(node->pos,node->ori);
 			GLUtils::RevolvedRectangle(cylBox,CompUtils::mapColor(glColor),glSlices);
--- a/pkg/dem/Particle.cpp
+++ b/pkg/dem/Particle.cpp
@@ -139,7 +139,7 @@
 shared_ptr<Node> Shape::setFromRaw_helper_nodeFromCoords(vector<shared_ptr<Node>>& nn, const vector<Real>& raw, size_t pos){
 	if(raw.size()<pos+3){ LOG_ERROR("Raw data too short (length "<<raw.size()<<", pos="<<pos<<"; this should be checked automatically before invoking this function."); throw std::logic_error("Error in setFromRaw_helper_nodeFromCoords: see error message."); }
 	Vector3r p(raw[pos],raw[pos+1],raw[pos+2]);
-	if(isnan(p[0]) || isnan(p[1])){ //return existing node
+	if(std::isnan(p[0]) || std::isnan(p[1])){ //return existing node
 		int p2i=int(p[2]);
 		if(!(p2i>=0 && p2i<(int)nn.size())) throw std::runtime_error("Raw coords beginning with NaN signify an existing node, but the index (z-component) is "+to_string(p[2])+" ("+to_string(p2i)+" as int), which is not a valid index (0.."+to_string(nn.size()-1)+") of existing nodes.");
 		return nn[p2i];
@@ -402,8 +402,8 @@
 			break; // don't iterate further, the iterator is invalidated by deletion
 		}
 	}
-	if(!isnan(massMult)){ dyn.mass*=massMult; dyn2.mass*=massMult; }
-	if(!isnan(inertiaMult)){ dyn.inertia*=inertiaMult; dyn2.inertia*=inertiaMult; }
+	if(!std::isnan(massMult)){ dyn.mass*=massMult; dyn2.mass*=massMult; }
+	if(!std::isnan(inertiaMult)){ dyn.inertia*=inertiaMult; dyn2.inertia*=inertiaMult; }
 	pyNodesAppend(clone); // add to DemField.nodes
 	return ret;
 }
--- a/pkg/dem/Pellet.cpp
+++ b/pkg/dem/Pellet.cpp
@@ -121,7 +121,7 @@
 		}
 		Ft*=ratio;
 	}
-	assert(!isnan(Fn)); assert(!isnan(Ft[0]) && !isnan(Ft[1]));
+	assert(!std::isnan(Fn)); assert(!std::isnan(Ft[0]) && !std::isnan(Ft[1]));
 	// elastic potential energy
 	if(unlikely(scene->trackEnergy)) scene->energy->add(0.5*(pow(Fn,2)/ph.kn+Ft.squaredNorm()/ph.kt),"elast",elastPotIx,EnergyTracker::IsResettable);
 	return true;
@@ -131,10 +131,10 @@
 void PelletAgglomerator::run(){
 	//DemField& dem(field->cast<DemField>());
 	// loop over all source particles, and loop over all contacts of each of them
-	if(isnan(massIncPerRad)) throw std::runtime_error("PalletAgglomerator.massIncPerRad==NaN (must be specified)");
+	if(std::isnan(massIncPerRad)) throw std::runtime_error("PalletAgglomerator.massIncPerRad==NaN (must be specified)");
 	if(dampHalfLife<0) dampHalfLife*=-scene->dt;
 	Real sumDMass=0.;
-	Real lambda=(dampHalfLife==0 || isnan(dampHalfLife))?0:(log(2)/dampHalfLife);
+	Real lambda=(dampHalfLife==0 || std::isnan(dampHalfLife))?0:(log(2)/dampHalfLife);
 	for(const shared_ptr<Particle>& src: agglomSrcs){
 		for(const auto& idCon: src->contacts){
 			const shared_ptr<Contact>& c(idCon.second);
--- a/pkg/dem/PeriIsoCompressor.cpp
+++ b/pkg/dem/PeriIsoCompressor.cpp
@@ -53,7 +53,7 @@
 	Vector3r cellArea=Vector3r(cellSize[1]*cellSize[2],cellSize[0]*cellSize[2],cellSize[0]*cellSize[1]);
 	Real minSize=min(cellSize[0],min(cellSize[1],cellSize[2])), maxSize=max(cellSize[0],max(cellSize[1],cellSize[2]));
 	if(minSize<2.1*maxSpan){ throw runtime_error("Minimum cell size is smaller than 2.1*span_of_the_biggest_body! (periodic collider requirement)"); }
-	if(((step%globalUpdateInt)==0) || isnan(avgStiffness) || isnan(sigma[0]) || isnan(sigma[1])|| isnan(sigma[2])){
+	if(((step%globalUpdateInt)==0) || std::isnan(avgStiffness) || std::isnan(sigma[0]) || std::isnan(sigma[1])|| std::isnan(sigma[2])){
 		avgStressIsoStiffness(cellArea,sigma,avgStiffness);
 		LOG_TRACE("Updated sigma="<<sigma<<", avgStiffness="<<avgStiffness);
 	}
@@ -131,13 +131,13 @@
 		Matrix6r stiffness;
 		std::tie(stress,stiffness)=DemFuncs::stressStiffness(scene,dem,/*skipMultinodal*/false,scene->cell->getVolume()*relVol);
 	}
-	if(isnan(mass) || mass<=0){ throw std::runtime_error("WeirdTriaxControl.mass must be positive, not "+to_string(mass)); }
+	if(std::isnan(mass) || mass<=0){ throw std::runtime_error("WeirdTriaxControl.mass must be positive, not "+to_string(mass)); }
 
 	bool allOk=true;
 
 	maxStrainedStress=NaN;
 	// maximum stress along strain-prescribed axes
-	for(int ax:{0,1,2}){ if((stressMask&(1<<ax))==0 && (maxStrainedStress<abs(stress(ax,ax)) || isnan(maxStrainedStress))) maxStrainedStress=abs(stress(ax,ax)); }
+	for(int ax:{0,1,2}){ if((stressMask&(1<<ax))==0 && (maxStrainedStress<abs(stress(ax,ax)) || std::isnan(maxStrainedStress))) maxStrainedStress=abs(stress(ax,ax)); }
 
 
 	// apply condition along each axis separately (stress or strain)
@@ -164,7 +164,7 @@
 		if(stressMask&(1<<axis)){
 			Real curr=stress(axis,axis);
 			if(goal[axis]!=0 && relStressTol>0. && abs((curr-goal[axis])/goal[axis])>relStressTol) allOk=false;
-			else if(relStressTol<0 && !isnan(maxStrainedStress) && abs((curr-goal[axis])/maxStrainedStress)>abs(relStressTol)) allOk=false;
+			else if(relStressTol<0 && !std::isnan(maxStrainedStress) && abs((curr-goal[axis])/maxStrainedStress)>abs(relStressTol)) allOk=false;
 			else if(absStressTol>0 && abs(curr-goal[axis])>absStressTol) allOk=false;
 		}else{
 			Real curr=strain[axis];
--- a/pkg/dem/ShapePack.cpp
+++ b/pkg/dem/ShapePack.cpp
@@ -65,7 +65,7 @@
 	if(scale!=1.) ret->applyScale(scale);
 	if(nodes.empty()) throw std::runtime_error("Programming error: RawShape::toShape: "+className+"::setFromRaw did not set any nodes.");
 
-	if(!isnan(density)){
+	if(!std::isnan(density)){
 		for(const auto& n: nodes){
 			n->setData<DemData>(make_shared<DemData>());
 			#ifdef WOO_OPENGL
@@ -218,7 +218,7 @@
 	// one particle: do not clump
 	if(shsh.size()==1 && shsh[0]->nodes.size()==1){
 		const auto& n(shsh[0]->nodes[0]);
-		if(!isnan(clumpPos.maxCoeff())){ n->pos=clumpPos; n->ori=clumpOri*n->ori; }
+		if(!std::isnan(clumpPos.maxCoeff())){ n->pos=clumpPos; n->ori=clumpOri*n->ori; }
 		return std::make_tuple(vector<shared_ptr<Node>>({n}),par);
 	}
 	if(shsh.size()==1) LOG_WARN("RawShapeClump.makeParticle: clumping node of a single multi-nodal particle.");
@@ -248,7 +248,7 @@
 	cd->inertia=mat->density*inertia*pow(scale,5);
 	cd->equivRad=equivRad;
 
-	if(!isnan(clumpPos.maxCoeff())){
+	if(!std::isnan(clumpPos.maxCoeff())){
 		LOG_FATAL(__FILE__<<":"<<__LINE__<<": specifying clumpPos/clumpOri not yet implemented, garbage will be returned!");
 		cn->pos=clumpPos;
 		cn->ori=clumpOri;
@@ -342,7 +342,7 @@
 		scene->isPeriodic=false;
 	}
 	for(const auto& rr: raws){
-		Real _color=(isnan(color)?Mathr::UnitRandom():color);
+		Real _color=(std::isnan(color)?Mathr::UnitRandom():color);
 		vector<shared_ptr<Node>> nodes;
 		vector<shared_ptr<Particle>> pp;
 		std::tie(nodes,pp)=rr->makeParticles(/*mat*/mat,/*clumpPos: force natural position*/Vector3r(NaN,NaN,NaN),/*ori: ignored*/Quaternionr::Identity(),/*mask*/mask,/*scale*/1.);
--- a/pkg/dem/Sphere.cpp
+++ b/pkg/dem/Sphere.cpp
@@ -126,7 +126,7 @@
 		#ifdef WOO_DEBUG
 			const Particle *pA=C->leakPA(), *pB=C->leakPB();
 			bool isPA=(pA==particle.get()); // int sign=(isPA?1:-1);
-			if(isnan(F[0])||isnan(F[1])||isnan(F[2])||isnan(T[0])||isnan(T[1])||isnan(T[2])){
+			if(std::isnan(F[0])||std::isnan(F[1])||std::isnan(F[2])||std::isnan(T[0])||std::isnan(T[1])||std::isnan(T[2])){
 				std::ostringstream oss; oss<<"NaN force/torque on particle #"<<particle->id<<" from ##"<<pA->id<<"+"<<pB->id<<":\n\tF="<<F<<", T="<<T; //"\n\tlocal F="<<C->phys->force*sign<<", T="<<C->phys->torque*sign<<"\n";
 				throw std::runtime_error(oss.str().c_str());
 			}
@@ -169,7 +169,7 @@
 	GLUtils::setLocalCoords(shape->nodes[0]->pos+shift+dPos,shape->nodes[0]->ori);
 
 	// for rendering ellipsoid
-	if(!isnan(scaleAxes[0])) glScalev(scaleAxes);
+	if(!std::isnan(scaleAxes[0])) glScalev(scaleAxes);
 
 	glClearDepth(1.0f);
 	glEnable(GL_NORMALIZE);
--- a/pkg/dem/Tracer.cpp
+++ b/pkg/dem/Tracer.cpp
@@ -96,8 +96,8 @@
 			} else {
 				ix=(writeIx+i)%pts.size();
 			}
-			if(!isnan(pts[ix][0])){
-				if(isnan(scalars[ix])){
+			if(!std::isnan(pts[ix][0])){
+				if(std::isnan(scalars[ix])){
 					// if there is no scalar and no scalar should be saved, color by history position
 					if(Tracer::scalar==Tracer::SCALAR_NONE) glColor3v(Tracer::lineColor->color((flags&FLAG_COMPRESS ? i*1./writeIx : i*1./pts.size())));
 					// if other scalars are saved, use noneColor to not destroy Tracer::lineColor range by auto-adjusting to bogus
@@ -120,7 +120,7 @@
 				else{
 					const auto& gl=n->getData<GlData>();
 					// don't scale if refpos is invalid
-					if(isnan(gl.refPos.maxCoeff())) glVertex3v(pt); 
+					if(std::isnan(gl.refPos.maxCoeff())) glVertex3v(pt); 
 					// x+(s-1)*(x-x0)
 					else glVertex3v((pt+((Renderer::dispScale-Vector3r::Ones()).array()*(pt-gl.refPos).array()).matrix()).eval());
 				}
@@ -278,7 +278,7 @@
 			const auto& pI(dyn.parRef.begin());
 			if(hasP && dynamic_pointer_cast<Sphere>((*pI)->shape)) radius=(*pI)->shape->cast<Sphere>().radius;
 			else if(dyn.isClump()) radius=dyn.cast<ClumpData>().equivRad;
-			if(rRange.maxCoeff()>0) hidden=(isnan(radius) || (rRange[0]>0 && radius<rRange[0]) || (rRange[1]>0 && radius>rRange[1]));
+			if(rRange.maxCoeff()>0) hidden=(std::isnan(radius) || (rRange[0]>0 && radius<rRange[0]) || (rRange[1]>0 && radius>rRange[1]));
 		}
 		if(tr.isHidden()!=hidden) tr.setHidden(hidden);
 		Real sc; // scalar by which the trace will be colored
--- a/pkg/dem/Truss.cpp
+++ b/pkg/dem/Truss.cpp
@@ -44,7 +44,7 @@
 	const Vector3r AB(t.nodes[1]->pos-t.nodes[0]->pos);
 	const Real len=AB.norm();
 	const Vector3r axUnit=AB/len;
-	if(isnan(t.l0)){
+	if(std::isnan(t.l0)){
 		if(setL0) t.l0=len;
 		else woo::ValueError(("#"+lexical_cast<string>(particle->id)+": Truss.l0==NaN (set In2_Truss_ElastMat.setL0=True to initialize this value automatically."));
 	}
--- a/pkg/dem/VtkExport.cpp
+++ b/pkg/dem/VtkExport.cpp
@@ -374,7 +374,7 @@
 			tCellNum=addTriangulatedObject(vert,tri,tPos,tCells);
 		}
 		else if(wall){
-			if(isnan(wall->glAB.volume())){
+			if(std::isnan(wall->glAB.volume())){
 				if(infError) throw std::runtime_error("Wall #"+to_string(p->id)+" does not have Wall.glAB set and cannot be exported to VTK with VtkExport.infError=True.");
 				else continue; // skip otherwise
 			}
@@ -395,7 +395,7 @@
 			mCellNum=addTriangulatedObject({node->loc2glob(A),node->loc2glob(B),node->loc2glob(C),node->loc2glob(D)},{Vector3i(0,1,3),Vector3i(0,3,2)},mPos,mCells);
 		}
 		else if(infCyl){
-			if(isnan(infCyl->glAB.squaredNorm())){
+			if(std::isnan(infCyl->glAB.squaredNorm())){
 				if(infError) throw std::runtime_error("InfCylinder #"+to_string(p->id)+" does not have InfCylinder.glAB set and cannot be exported to VTK with VtkExport.infError=True.");
 				else continue; // skip the particles otherwise
 			}
@@ -465,13 +465,13 @@
 				scalar=p->matState->getScalar(0,scene->step);
 				if(facet) scalar/=p->shape->cast<Facet>().getArea();
 			}
-			mMatState->InsertNextValue(isnan(scalar)?nanValue:scalar);
+			mMatState->InsertNextValue(std::isnan(scalar)?nanValue:scalar);
 			mSigNorm->InsertNextValue(sigNorm);
 		}
 		// triangulated particles (ellipsoids, capsules)
 		for(int i=0;i<tCellNum;i++){
 			Real r=p->shape->equivRadius();
-			tEqRad->InsertNextValue(isnan(r)?-1:r);
+			tEqRad->InsertNextValue(std::isnan(r)?-1:r);
 			tColor->InsertNextValue(p->shape->color);
 			tMatId->InsertNextValue(p->material->id);
 			// velocity values are erroneous for multi-nodal particles (facets), don't care now
@@ -479,7 +479,7 @@
 			tAngVel->InsertNextTupleValue(dyn.angVel.data());
 			Real scalar=NaN;
 			if(p->matState){ scalar=p->matState->getScalar(0,scene->step);	/* if(facet) scalar/=p->shape->cast<Facet>().getArea(); */ }
-			tMatState->InsertNextValue(isnan(scalar)?nanValue:scalar);
+			tMatState->InsertNextValue(std::isnan(scalar)?nanValue:scalar);
 		}
 	}
 
--- a/pkg/dem/Wall.cpp
+++ b/pkg/dem/Wall.cpp
@@ -167,7 +167,7 @@
 			else A[ax0]=CompUtils::wrapNum(pos[ax0],hSize[ax0]);
 			unit1=Vector3r::Unit(ax1)*hSize[ax1]/div;
 			unit2=Vector3r::Unit(ax2)*hSize[ax2]/div;
-		} else if(isnan(wall.glAB.min()[0])){
+		} else if(std::isnan(wall.glAB.min()[0])){
 			A=viewInfo.sceneCenter-Vector3r::Ones()*viewInfo.sceneRadius;
 			A[ax0]=pos[ax0];
 			unit1=Vector3r::Unit(ax1)*2*viewInfo.sceneRadius/div;
--- a/pkg/fem/Membrane.cpp
+++ b/pkg/fem/Membrane.cpp
@@ -82,7 +82,7 @@
 		#endif
 	)) return; 
 	// check thickness
-	Real t=(isnan(thickness)?2*this->halfThick:thickness);
+	Real t=(std::isnan(thickness)?2*this->halfThick:thickness);
 	if(/*also covers NaN*/!(t>0)) throw std::runtime_error("Membrane::ensureStiffnessMatrices: Facet thickness is not positive!");
 
 	// plane stress stiffness matrix
@@ -110,8 +110,8 @@
 
 	// strain-displacement matrix (DKT element)
 
-	Real dktT=(isnan(bendThickness)?t:bendThickness);
-	assert(!isnan(dktT));
+	Real dktT=(std::isnan(bendThickness)?t:bendThickness);
+	assert(!std::isnan(dktT));
 
 	// [Batoz,Bathe,Ho: 1980], Appendix A: Expansions for the DKT element
 	// (using the same notation)
@@ -375,7 +375,7 @@
 	LOG_TRACE("DKT: "<<Fdkt.transpose())
 	// surface load, if any
 	Real surfLoadForce=0.;
-	if(!isnan(ff.surfLoad) && ff.surfLoad!=0.){ surfLoadForce=(1/3.)*ff.getArea()*ff.surfLoad; }
+	if(!std::isnan(ff.surfLoad) && ff.surfLoad!=0.){ surfLoadForce=(1/3.)*ff.getArea()*ff.surfLoad; }
 	// apply nodal forces
 	for(int i:{0,1,2}){
 		Vector3r Fl=Vector3r(Fcst[2*i],Fcst[2*i+1],Fdkt[3*i]+surfLoadForce);
@@ -431,7 +431,7 @@
 			GLUtils::GLDrawArrow(nodePt3,p1,c1,/*doubled*/arrow>1);
 		}
 	}
-	if(!isnan(z)){
+	if(!std::isnan(z)){
 		glLineWidth(lineWd);
 		GLUtils::GLDrawLine(nodePt3,Vector3r(nodePt[0],nodePt[1],z),range->color(z));
 	}
--- a/pkg/gl/NodeGlRep.cpp
+++ b/pkg/gl/NodeGlRep.cpp
@@ -58,7 +58,7 @@
 	Vector3r color=(range?range->color(valNorm):CompUtils::scalarOnColorScale(valNorm,0,1));
 	Real mxNorm=(range?range->mnmx[1]:1);
 	Real len=relSz*viewInfo->sceneRadius;
-	if(!isnan(scaleExp)) len*=pow(min(1.,valNorm/mxNorm),scaleExp);
+	if(!std::isnan(scaleExp)) len*=pow(min(1.,valNorm/mxNorm),scaleExp);
 	Vector3r pos=node->pos+(node->hasData<GlData>()?node->getData<GlData>().dGlPos:Vector3r::Zero());
 	glColor3v(color);
 	GLUtils::GLDrawArrow(pos,pos+len*(val/valNorm),color);
@@ -135,7 +135,7 @@
 		Vector3r color=(range?range->color(eigVal[i]):CompUtils::scalarOnColorScale(eigVal[i],-1,1));
 		Real mxNorm=(range?range->maxAbs(eigVal[i]):1);
 		Real len=relSz*viewInfo->sceneRadius;
-		len*=isnan(scaleExp)?abs(eigVal[i]/mxNorm):pow(abs(eigVal[i])/mxNorm,scaleExp);
+		len*=std::isnan(scaleExp)?abs(eigVal[i]/mxNorm):pow(abs(eigVal[i])/mxNorm,scaleExp);
 		glColor3v(color);
 		Vector3r dx(len*eigVec.col(i));
 		// arrows which go towards each other for negative eigenvalues, and away from each other for positive ones
@@ -172,8 +172,8 @@
 
 
 void CylGlRep::render(const shared_ptr<Node>& node, const GLViewInfo* viewInfo){
-	Real radius=viewInfo->sceneRadius*relSz*(isnan(rad)?1:(rangeRad?rangeRad->norm(rad):1));
-	Real ccol=isnan(col)?0:col;
+	Real radius=viewInfo->sceneRadius*relSz*(std::isnan(rad)?1:(rangeRad?rangeRad->norm(rad):1));
+	Real ccol=std::isnan(col)?0:col;
 	Vector3r color=(rangeCol?rangeCol->color(ccol):CompUtils::scalarOnColorScale(ccol,0,1));
 	Vector3r A=(node->pos+node->ori.conjugate()*Vector3r(xx[0],0,0)), B=(node->pos+node->ori.conjugate()*Vector3r(xx[1],0,0));
 	// cerr<<"A="<<A.transpose()<<", B="<<B.transpose()<<", r="<<radius<<endl;
--- a/pkg/gl/Renderer.cpp
+++ b/pkg/gl/Renderer.cpp
@@ -146,8 +146,8 @@
 	bool rendered=!pointClipped(cellPos);
 	// this encodes that the node is clipped
 	if(!rendered){ gld.dGlPos=Vector3r(NaN,NaN,NaN); return; }
-	if(updateRefPos || isnan(gld.refPos[0])) gld.refPos=n->pos;
-	if(updateRefPos || isnan(gld.refOri.x())) gld.refOri=n->ori;
+	if(updateRefPos || std::isnan(gld.refPos[0])) gld.refPos=n->pos;
+	if(updateRefPos || std::isnan(gld.refOri.x())) gld.refOri=n->ori;
 	const Vector3r& pos=n->pos; const Vector3r& refPos=gld.refPos;
 	const Quaternionr& ori=n->ori; const Quaternionr& refOri=gld.refOri;
 	// if no scaling and no periodic, return quickly
@@ -335,7 +335,7 @@
 	Vector3r x;
 	if(node->hasData<GlData>()){
 		x=node->pos+node->getData<GlData>().dGlPos; // pos+dGlPos is already canonicalized, if periodic
-		if(isnan(x[0])) return;
+		if(std::isnan(x[0])) return;
 	}
 	else{ x=(scene->isPeriodic?scene->cell->canonicalizePt(node->pos):node->pos); }
 	if(likely(!Renderer::fastDraw)){
--- a/pkg/sparc/SparcField.cpp
+++ b/pkg/sparc/SparcField.cpp
@@ -40,10 +40,10 @@
 	locDirty=false;
 };
 
-template<typename M> bool eig_isnan(const M& m){for(int j=0; j<m.cols(); j++)for(int i=0;i<m.rows(); i++) if(isnan(m(i,j))) return true; return false; }
-template<typename M> bool eig_all_isnan(const M&m){for(int j=0; j<m.cols(); j++)for(int i=0;i<m.rows();i++) if(!isnan(m(i,j))) return false; return true; }
-template<> bool eig_isnan<Vector3r>(const Vector3r& v){for(int i=0; i<v.size(); i++) if(isnan(v[i])) return true; return false; }
-template<> bool eig_isnan(const Real& r){ return isnan(r); }
+template<typename M> bool eig_isnan(const M& m){for(int j=0; j<m.cols(); j++)for(int i=0;i<m.rows(); i++) if(std::isnan(m(i,j))) return true; return false; }
+template<typename M> bool eig_all_isnan(const M&m){for(int j=0; j<m.cols(); j++)for(int i=0;i<m.rows();i++) if(!std::isnan(m(i,j))) return false; return true; }
+template<> bool eig_isnan<Vector3r>(const Vector3r& v){for(int i=0; i<v.size(); i++) if(std::isnan(v[i])) return true; return false; }
+template<> bool eig_isnan(const Real& r){ return std::isnan(r); }
 
 vector<shared_ptr<Node>> SparcField::nodesAround(const Vector3r& pt, int count, Real radius, const shared_ptr<Node>& self, Real* relLocPtDens, const Vector2i& mnMxPts){
 	if(!locator) throw runtime_error("SparcField::locator not initialized!");	
@@ -396,7 +396,7 @@
 	SparcData& dta(n->getData<SparcData>());
 	Vector3r locVel=n->ori*dta.v;
 	for(int i=0;i<3;i++){
-		if(!isnan(dta.fixedV[i])) locVel[i]=dta.fixedV[i];
+		if(!std::isnan(dta.fixedV[i])) locVel[i]=dta.fixedV[i];
 	}
 	dta.v=n->ori.conjugate()*locVel;
 	if(!permitFixedDivT && !eig_all_isnan(dta.fixedT)){
@@ -435,7 +435,7 @@
 py::list SparcData::getGFixedAny(const Vector3r& any, const Quaternionr& ori){
 	py::list ret;
 	for(int i=0;i<3;i++){
-		if(isnan(any[i])) continue;
+		if(std::isnan(any[i])) continue;
 		Vector3r a=Vector3r::Zero(); a[i]=1;
 		ret.append(py::make_tuple(any[i],ori*a));
 	}
@@ -447,7 +447,7 @@
 	// this should automatically zero rotation vector if 2 or 3 axes are fixed
 	Matrix3r W=getW();
 	Vector3r rot(W(1,2),W(0,2),W(0,1));
-	for(int ax:{0,1,2}) if(!isnan(fixedV[ax])) rot=Vector3r::Unit(ax)*rot.dot(Vector3r::Unit(ax));
+	for(int ax:{0,1,2}) if(!std::isnan(fixedV[ax])) rot=Vector3r::Unit(ax)*rot.dot(Vector3r::Unit(ax));
 	Real angle=rot.norm();
 	if(angle>0) return Quaternionr(AngleAxisr(angle*dt,rot/angle));
 	return Quaternionr::Identity();
@@ -549,8 +549,8 @@
 	for(const shared_ptr<Node>& n: field->nodes){
 		SparcData& dta=n->getData<SparcData>();
 		for(int ax:{0,1,2}){
-			assert(!(!isnan(dta.fixedV[ax]) && dta.dofs[ax]>=0)); // handled by assignDofs
-			assert(isnan(dta.fixedV[ax]) || dta.dofs[ax]<0);
+			assert(!(!std::isnan(dta.fixedV[ax]) && dta.dofs[ax]>=0)); // handled by assignDofs
+			assert(std::isnan(dta.fixedV[ax]) || dta.dofs[ax]<0);
 			if(ax<dim){
 				// in the spanned space
 				dta.locV[ax]=dta.dofs[ax]<0?dta.fixedV[ax]:v[dta.dofs[ax]];
@@ -559,11 +559,11 @@
 				// don't move out of the space (assignDofs check local rotation is not out-of-plane)
 				dta.locV[ax]=0; 
 				if(dta.dofs[ax]>=0){ // prescribed stress; in that case v[dof] is L(ax,ax)
-					assert(!isnan(Tout[ax]));
+					assert(!std::isnan(Tout[ax]));
 					dta.Lout[ax]=v[dta.dofs[ax]];
 				} else {
 					// in out-of-space deformation dta.Lout[ax] is prescribed, just leave that one alone
-					assert(!isnan(dta.Lout[ax]));
+					assert(!std::isnan(dta.Lout[ax]));
 				}
 			}
 		}
@@ -575,7 +575,7 @@
 	int nid=0, dof=0;
 	// check that Tout is only prescribed where it makes sense
 	for(int ax=0; ax<dim; ax++){
-		if(!isnan(Tout[ax])) woo::ValueError("StaticEquilibriumSolver.Tout["+to_string(ax)+" must be NaN, since the space is "+to_string(dim)+"d (only out-of-space components may be assigned)");
+		if(!std::isnan(Tout[ax])) woo::ValueError("StaticEquilibriumSolver.Tout["+to_string(ax)+" must be NaN, since the space is "+to_string(dim)+"d (only out-of-space components may be assigned)");
 	}
 	for(const shared_ptr<Node>& n: field->nodes){
 		SparcData& dta=n->getData<SparcData>();
@@ -593,13 +593,13 @@
 		}
 		for(int ax:{0,1,2}){
 			if(ax<dim){
-				if(!isnan(dta.fixedV[ax])) dta.dofs[ax]=-1;
+				if(!std::isnan(dta.fixedV[ax])) dta.dofs[ax]=-1;
 				else dta.dofs[ax]=dof++;
 			} else {
-				if(!isnan(dta.fixedV[ax])) woo::ValueError("Node "+to_string(nid)+" prescribes fixedV["+to_string(ax)+"]: not allowed in "+to_string(dim)+"d problems (would move out of basis space); use Lout in each point to prescribe diagonal gradV components.");
-				if(!isnan(dta.fixedT[ax])) woo::ValueError("Node "+to_string(nid)+" prescribed fixedT["+to_string(ax)+"]: not allowed in "+to_string(dim)+"d problems, use ExplicitNodeIntegrator.Tout (the same for all points)");
+				if(!std::isnan(dta.fixedV[ax])) woo::ValueError("Node "+to_string(nid)+" prescribes fixedV["+to_string(ax)+"]: not allowed in "+to_string(dim)+"d problems (would move out of basis space); use Lout in each point to prescribe diagonal gradV components.");
+				if(!std::isnan(dta.fixedT[ax])) woo::ValueError("Node "+to_string(nid)+" prescribed fixedT["+to_string(ax)+"]: not allowed in "+to_string(dim)+"d problems, use ExplicitNodeIntegrator.Tout (the same for all points)");
 				// stress prescribed along this axis, gradV is then unknown in that direction
-				if(!isnan(Tout[ax])){
+				if(!std::isnan(Tout[ax])){
 					// recycle some of the previous dofs if Tout was the same (with symm01d only)
 					// (== checks also the previous value, as it will be false if any of the operands is NaN)
 					if(symm01d && ((ax==1 && Tout[1]==Tout[0]) || (ax==2 && Tout[2]==Tout[0]))){ assert(dta.dofs[0]>=0); dta.dofs[ax]=dta.dofs[0]; }
@@ -622,8 +622,8 @@
 			if(dta.dofs[ax]<0) continue;
 			if(ax>=dim){
 				// if Tout[ax] are not prescribed, then there should be no unknown here at all
-				assert(!isnan(Tout[ax]));
-				if(isnan(dta.Lout[ax])) woo::ValueError("Node "+to_string(dta.nid)+": Lout["+to_string(ax)+"] must not be NaN when out-of-space stress Tout["+to_string(ax)+"] is prescribed; the value will be changed automatically).");
+				assert(!std::isnan(Tout[ax]));
+				if(std::isnan(dta.Lout[ax])) woo::ValueError("Node "+to_string(dta.nid)+": Lout["+to_string(ax)+"] must not be NaN when out-of-space stress Tout["+to_string(ax)+"] is prescribed; the value will be changed automatically).");
 				ret[dta.dofs[ax]]=dta.Lout[ax];
 			} 
 			else if(useZero){ ret[dta.dofs[ax]]=0.; }
@@ -719,7 +719,7 @@
 void StaticEquilibriumSolver::computeConstraintErrors(const shared_ptr<Node>& n, const Vector3r& divT, VectorXr& resid){
 	SparcData& dta(n->getData<SparcData>());
 	#ifdef WOO_DEBUG
-		for(int i=0;i<3;i++) if(!isnan(dta.fixedV[i])&&!isnan(dta.fixedT[i])) throw std::invalid_argument((boost::format("Nid %d: both velocity and stress prescribed along local axis %d (axis %s in global space)") %dta.nid %i %(n->ori.conjugate()*(i==0?Vector3r::UnitX():(i==1?Vector3r::UnitY():Vector3r::UnitZ()))).transpose()).str());
+		for(int i=0;i<3;i++) if(!std::isnan(dta.fixedV[i])&&!std::isnan(dta.fixedT[i])) throw std::invalid_argument((boost::format("Nid %d: both velocity and stress prescribed along local axis %d (axis %s in global space)") %dta.nid %i %(n->ori.conjugate()*(i==0?Vector3r::UnitX():(i==1?Vector3r::UnitY():Vector3r::UnitZ()))).transpose()).str());
 	#endif
 	#define _WATCH_NID(aaa) SPARC_TRACE_OUT("           "<<aaa<<endl); if(dta.nid==watch) cerr<<aaa<<endl;
 	#ifdef SPARC_INSPECT
@@ -736,18 +736,18 @@
 		// velocity is prescribed; if not spanned, strain is prescribed, i.e. Tout[ax] are NaN
 		int dof=dta.dofs[ax];
 		if(dof<0){
-			assert((ax<dim && !isnan(dta.fixedV[ax])) || (ax>=dim && isnan(Tout[ax])));
+			assert((ax<dim && !std::isnan(dta.fixedV[ax])) || (ax>=dim && std::isnan(Tout[ax])));
 			continue;
 		}
 		if(ax>=dim) { // out-of-space dimension
-			assert(!isnan(Tout[ax])); // it must not be NaN (i.e. prescribed L??): there would be no dof there
+			assert(!std::isnan(Tout[ax])); // it must not be NaN (i.e. prescribed L??): there would be no dof there
 			resid[dof]=-(Tout[ax]-locT(ax,ax)); // difference between out-of-dimension stress and current stress
 			#ifdef SPARC_TRACE
 				if(dbgFlags&DBG_DOFERR) _WATCH_NID("\tnid "<<dta.nid<<" dof "<<dof<<" (out-of-space): locT["<<ax<<","<<ax<<"]="<<locT(ax,ax)<<" (should be "<<Tout[ax]<<") sets resid["<<dof<<"]="<<resid[dof]);
 			#endif
 		} else { // regular (boring) dimension
 			// nothing prescribed, divT is the residual
-			if(isnan(dta.fixedT[ax])){
+			if(std::isnan(dta.fixedT[ax])){
 				// NB: dta.divT is not the current value, that exists only with SPARC_INSPECT
 				Vector3r locDivT=oriTrsf*divT;
 				resid[dof]=charLen*locDivT[ax];
@@ -1134,7 +1134,7 @@
 	Vector3r A(posIsA?pos:pos-vec), B(posIsA?pos+vec:pos);
 	GLUtils::GLDrawArrow(A,B,color);
 	if(doubleHead) GLUtils::GLDrawArrow(A,A+.9*(B-A),color);
-	if(!isnan(num)) GLUtils::GLDrawNum(num,posIsA?B:A,Vector3r::Ones());
+	if(!std::isnan(num)) GLUtils::GLDrawNum(num,posIsA?B:A,Vector3r::Ones());
 }
 
 void SparcConstraintGlRep::render(const shared_ptr<Node>& node, const GLViewInfo* viewInfo){
@@ -1145,7 +1145,7 @@
 		for(int j:{0,1}){
 			bool isV=(j==0);
 			Real val=(isV?fixedV[i]:fixedT[i]);
-			if(isnan(val)) continue;
+			if(std::isnan(val)) continue;
 			#if 0
 				const Vector2r& cMnMx=(isV?vColor:tColor);
 				const shared_ptr<ScalarRange>& rg=(isV?vRange:tRange);
--- a/py/_packPredicates.cpp
+++ b/py/_packPredicates.cpp
@@ -368,7 +368,7 @@
 	Vector3r off=Vector3r::Zero();
 	auto sbox=sp->aabb();
 	auto pbox=p->aabb();
-	if(recenter && !isinf(pbox.sizes().maxCoeff())){
+	if(recenter && !std::isinf(pbox.sizes().maxCoeff())){
 		off=pbox.center()-sbox.center();
 		// it is sphere which are shifted by *off* below, so move also sbox here (only)
 		sbox.translate(off);
--- a/py/_triangulated.cpp
+++ b/py/_triangulated.cpp
@@ -36,7 +36,7 @@
 }
 
 int spheroidsToSTL(const string& out, const shared_ptr<DemField>& dem, Real tol, const string& solid, int mask, bool append, bool clipCell){
-	if(tol==0 || isnan(tol)) throw std::runtime_error("tol must be non-zero.");
+	if(tol==0 || std::isnan(tol)) throw std::runtime_error("tol must be non-zero.");
 	// first traversal to find reference radius
 	auto particleOk=[&](const shared_ptr<Particle>&p){ return (mask==0 || (p->mask & mask)) && (p->shape->isA<Sphere>() || p->shape->isA<Ellipsoid>() || p->shape->isA<Capsule>()); };
 	int numTri=0;
@@ -47,7 +47,7 @@
 		for(const auto& p: *dem->particles){
 			if(particleOk(p)) minRad=min(minRad,p->shape->equivRadius());
 		}
-		if(isinf(minRad) || isnan(minRad)) throw std::runtime_error("Minimum radius not found (relative tolerance specified); no matching particles?");
+		if(std::isinf(minRad) || std::isnan(minRad)) throw std::runtime_error("Minimum radius not found (relative tolerance specified); no matching particles?");
 		tol=-minRad*tol;
 		LOG_DEBUG("Minimum radius "<<minRad<<".");
 	}
--- a/py/_utils2.cpp
+++ b/py/_utils2.cpp
@@ -97,7 +97,7 @@
 	// compute velGrad work in periodic simulations
 	Real work=NaN;
 	if(scene->isPeriodic){
-		Matrix3r midStress=!isnan(prevStress[0])?.5*(voigt_toSymmTensor(prevStress)+stress):stress;
+		Matrix3r midStress=!std::isnan(prevStress[0])?.5*(voigt_toSymmTensor(prevStress)+stress):stress;
 		Real midVolume=(scene->cell->hSize-.5*scene->dt*scene->cell->gradV).determinant();
 		work=-(scene->cell->gradV*midStress).trace()*scene->dt*midVolume;
 	}
--- a/pkg/dem/Clump.hpp
+++ b/pkg/dem/Clump.hpp
@@ -11,7 +11,7 @@
 	// may fail when called from postLoad, but not from ensureOk()
 	void recompute(int div, bool failOk=false, bool fastOnly=false) WOO_CXX11_OVERRIDE;
 	void makeInvalid(){ volume=equivRad=NaN; inertia=Vector3r(NaN,NaN,NaN); pos=Vector3r::Zero(); ori=Quaternionr::Identity(); }
-	bool isOk() const { return !isnan(volume); }
+	bool isOk() const { return !std::isnan(volume); }
 	void ensureOk() { if(!isOk()) recompute(div,/*failOk*/false); }
 	std::tuple<vector<shared_ptr<Node>>,vector<shared_ptr<Particle>>> makeParticles(const shared_ptr<Material>&, const Vector3r& pos, const Quaternionr& ori, int mask, Real scale=1.) WOO_CXX11_OVERRIDE;
 	// void ensureApproxPos() WOO_CXX11_OVERRIDE;
--- a/pkg/dem/Concrete.hpp
+++ b/pkg/dem/Concrete.hpp
@@ -132,7 +132,7 @@
 				ret=(pow(sigmaN-yieldEllipseShift,2)/(-yieldEllipseShift*coh0/((1-omega)*tanPhi)+pow(yieldEllipseShift,2)))>=1 ? 0 : sqrt((-coh0*((1-omega)*tanPhi)*yieldEllipseShift+pow(coh0,2))*(1-pow(sigmaN-yieldEllipseShift,2)/(-yieldEllipseShift*coh0/((1-omega)*tanPhi)+pow(yieldEllipseShift,2))))-omega*coh0; break;
 			default: throw std::logic_error("Law2_L6Geom_ConcretePhys::yieldSigmaTNorm: invalid value of yieldSurfType="+to_string(yieldSurfType));
 		}
-		assert(!isnan(ret));
+		assert(!std::isnan(ret));
 		return max(0.,ret);
 	}
 
--- a/pkg/dem/Conveyor.hpp
+++ b/pkg/dem/Conveyor.hpp
@@ -15,7 +15,7 @@
 	void setAttachedParticlesColor(const shared_ptr<Node>& n, Real c);
 	#ifdef WOO_OPENGL
 		void render(const GLViewInfo&) WOO_CXX11_OVERRIDE{
-			if(isnan(glColor)) return;
+			if(std::isnan(glColor)) return;
 			Inlet::renderMassAndRate(node->pos);
 		}
 	#endif
--- a/pkg/dem/Funcs.hpp
+++ b/pkg/dem/Funcs.hpp
@@ -62,14 +62,14 @@
 		bool emptyOk=false
 	){
 		/* determine dRange if not given */
-		if(isnan(dRange[0]) || isnan(dRange[1]) || dRange[0]<0 || dRange[1]<=0 || dRange[0]>=dRange[1]){
+		if(std::isnan(dRange[0]) || std::isnan(dRange[1]) || dRange[0]<0 || dRange[1]<=0 || dRange[0]>=dRange[1]){
 			dRange=Vector2r(Inf,-Inf);
 			for(const auto& p: particleRange){
 				Real d=diameterGetter(p);
 				if(d<dRange[0]) dRange[0]=d;
 				if(d>dRange[1]) dRange[1]=d;
 			}
-			if(isinf(dRange[0])){
+			if(std::isinf(dRange[0])){
 				if(!emptyOk) throw std::runtime_error("DemFuncs::psd: no spherical particles?");
 				else return vector<Vector2r>{Vector2r::Zero(),Vector2r::Zero()};
 			}
@@ -81,7 +81,7 @@
 			Real d=diameterGetter(p);
 			Real w=weightGetter(p);
 			// NaN diameter or weight, or zero weight make the particle effectively disappear
-			if(isnan(d) || isnan(w) || w==0.) continue;
+			if(std::isnan(d) || std::isnan(w) || w==0.) continue;
 			// particles beyong upper bound are discarded, though their weight is taken in account
 			weight+=w;
 			if(d>dRange[1]) continue;
--- a/pkg/dem/Impose.hpp
+++ b/pkg/dem/Impose.hpp
@@ -50,7 +50,7 @@
 	void velocity(const Scene* scene, const shared_ptr<Node>& n) WOO_CXX11_OVERRIDE {
 		Vector3r& vv(n->getData<DemData>().vel);
 		for(int ax:{0,1,2}){
-			if(isnan(freqs[ax])||isnan(amps[ax])) continue;
+			if(std::isnan(freqs[ax])||std::isnan(amps[ax])) continue;
 			Real omega=2*M_PI*freqs[ax];
 			vv[ax]=amps[ax]*omega*cos(omega*scene->time);
 		}
--- a/pkg/dem/Inlet.hpp
+++ b/pkg/dem/Inlet.hpp
@@ -14,7 +14,7 @@
 	// set current smoothed mass flow rate, given unsmoothed value from the current step
 	// handles NaN values if there is no previous value
 	void setCurrRate(Real currRateNoSmooth){
-		if(isnan(currRate)||stepPrev<0) currRate=currRateNoSmooth;
+		if(std::isnan(currRate)||stepPrev<0) currRate=currRateNoSmooth;
 		else currRate=(1-currRateSmooth)*currRate+currRateSmooth*currRateNoSmooth;
 	}
 	// return true when maximum mass/num of particles (or other termination condition) has been reached
@@ -98,7 +98,7 @@
 
 struct AlignedMinMaxShooter: public ParticleShooter{
 	void operator()(const shared_ptr<Node>& n) WOO_CXX11_OVERRIDE {
-		if(isnan(vRange.maxCoeff())){ throw std::runtime_error("AlignedMinMaxShooter.vRange: must not contain NaN."); }
+		if(std::isnan(vRange.maxCoeff())){ throw std::runtime_error("AlignedMinMaxShooter.vRange: must not contain NaN."); }
 		n->getData<DemData>().vel=dir*(vRange[0]+Mathr::UnitRandom()*(vRange[1]-vRange[0]));
 		n->getData<DemData>().angVel=Vector3r::Zero();
 	}
@@ -219,7 +219,7 @@
 
 	#ifdef WOO_OPENGL
 		void render(const GLViewInfo&) WOO_CXX11_OVERRIDE {
-			if(isnan(glColor)) return;
+			if(std::isnan(glColor)) return;
 			GLUtils::AlignedBox(box,CompUtils::mapColor(glColor));
 			renderMassAndRate(box.center());
 		}
--- a/pkg/dem/Particle.hpp
+++ b/pkg/dem/Particle.hpp
@@ -357,7 +357,7 @@
 	// color manipulation
 	Real getSignedBaseColor(){ return color-trunc(color); }
 	Real getBaseColor(){ return abs(color)-trunc(abs(color)); }
-	void setBaseColor(Real c){ if(isnan(c)) return; color=trunc(color)+(color<0?-1:1)*CompUtils::clamped(c,0,1); }
+	void setBaseColor(Real c){ if(std::isnan(c)) return; color=trunc(color)+(color<0?-1:1)*CompUtils::clamped(c,0,1); }
 	bool getWire() const { return color<0; }
 	void setWire(bool w){ color=(w?-1:1)*abs(color); }
 	bool getHighlighted() const { return abs(color)>=1 && abs(color)<2; }
--- a/pkg/dem/ShapePack.hpp
+++ b/pkg/dem/ShapePack.hpp
@@ -32,7 +32,7 @@
 	// may fail when called from postLoad, but not from ensureOk()
 	virtual void recompute(int div, bool failOk=false, bool fastOnly=false){ throw std::runtime_error("ShapeClump.recompute: this class is not to be used directly, derived classes should override recompute."); }
 	void makeInvalid(){ volume=equivRad=NaN; inertia=Vector3r(NaN,NaN,NaN); pos=Vector3r::Zero(); ori=Quaternionr::Identity(); }
-	bool isOk() const { return !isnan(volume); }
+	bool isOk() const { return !std::isnan(volume); }
 	void ensureOk() { if(!isOk()) recompute(div,/*failOk*/false); }
 	// fill *pos* as average bounding sphere position, without calling compute
 	// virtual void ensureApproxPos(){ throw std::runtime_error("ShapeClump.ensureApproxPos: this class is not to be used directly, derived classes should override ensureApproxPos."); }
--- a/pkg/dem/VtkExport.hpp
+++ b/pkg/dem/VtkExport.hpp
@@ -10,7 +10,7 @@
 	// avoid warnings in VTK headers for using sstream
 	#pragma GCC diagnostic ignored "-Wdeprecated"
 	// work around error in vtkMath.h?
-	__attribute__((unused))	static bool _isnan(double x){ return std::isnan(x); }
+	__attribute__((unused))	static bool isnan(double x){ return std::isnan(x); }
 	#include<vtkCellArray.h>
 	#include<vtkPoints.h>
 	#include<vtkPointData.h>
--- a/pkg/gl/GlData.hpp
+++ b/pkg/gl/GlData.hpp
@@ -8,7 +8,7 @@
 struct GlData: public NodeData{
 	const char* getterName() const WOO_CXX11_OVERRIDE { return "gl"; }
 	void setDataOnNode(Node& n) WOO_CXX11_OVERRIDE { n.setData(static_pointer_cast<GlData>(shared_from_this())); }
-	bool isClipped() const { return isnan(dGlPos[0]); }
+	bool isClipped() const { return std::isnan(dGlPos[0]); }
 	#define woo_gl_GlData__CLASS_BASE_DOC_ATTRS_PY \
 		GlData,NodeData,"Nodal data used for rendering.", \
 		((Vector3r,refPos,Vector3r(NaN,NaN,NaN),AttrTrait<>().lenUnit(),"Reference position (for displacement scaling)")) \
--- a/pkg/sparc/SparcField.hpp
+++ b/pkg/sparc/SparcField.hpp
@@ -301,7 +301,7 @@
 		njev++;
 		fnorm0=functor(x,fvec);
 		jacInv=jac.inverse();
-		if(isinf(jacInv.maxCoeff()) || isnan(jacInv.maxCoeff())){
+		if(std::isinf(jacInv.maxCoeff()) || std::isnan(jacInv.maxCoeff())){
 			Index r,c; Scalar j=jacInv.maxCoeff(&r,&c);
 			cerr<<"Maximum jacInv coeff at ("<<r<<","<<c<<") is "<<j<<endl;
 			if(retry<5) return recomputeJacobian(x,retry+1);
-- 
debian-science-maintainers mailing list
debian-science-maintainers@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-science-maintainers

Reply via email to