diff --git a/astest/cont001a.comm b/astest/cont001a.comm
index a71f2926832..f77608cc873 100644
--- a/astest/cont001a.comm
+++ b/astest/cont001a.comm
@@ -31,23 +31,24 @@ DEBUT(
test = CA.TestCase()
-Mail = LIRE_MAILLAGE(UNITE=20, FORMAT="MED")
+mesh = LIRE_MAILLAGE(UNITE=20, FORMAT="MED", INFO=2)
-Mail = MODI_MAILLAGE(
- reuse=Mail,
- MAILLAGE=Mail,
+mesh = MODI_MAILLAGE(
+ reuse=mesh,
+ MAILLAGE=mesh,
ORIE_PEAU=_F(GROUP_MA_PEAU=("Group_2", "Group_1", "Group_3", "Group_4")),
+ INFO=2,
)
MODI = AFFE_MODELE(
- MAILLAGE=Mail, AFFE=_F(GROUP_MA=("Haut", "Bas"), PHENOMENE="MECANIQUE", MODELISATION="DKT")
+ MAILLAGE=mesh, AFFE=_F(GROUP_MA=("Haut", "Bas"), PHENOMENE="MECANIQUE", MODELISATION="DKT")
)
CARAMECA = AFFE_CARA_ELEM(MODELE=MODI, COQUE=_F(GROUP_MA=("Haut", "Bas"), EPAIS=0.01))
MAT = DEFI_MATERIAU(ELAS=_F(E=20000, NU=0.3, ALPHA=0.01))
-CHMAT = AFFE_MATERIAU(MAILLAGE=Mail, AFFE=_F(TOUT="OUI", MATER=MAT))
+CHMAT = AFFE_MATERIAU(MAILLAGE=mesh, AFFE=_F(TOUT="OUI", MATER=MAT))
DF1 = DEFI_FONCTION(
NOM_PARA="INST",
@@ -108,41 +109,57 @@ DEFICO = DEFI_CONT(
),
)
-# some checks for the first zone :
-zone = DEFICO.getContactZone(0)
-test.assertEqual(zone.getMasterCellsFromNode(19), [12, 13])
-test.assertEqual(zone.getSlaveCellsFromNode(64), [61, 62])
-test.assertEqual(zone.getMasterCellNeighbors(14), [13, 15])
-test.assertEqual(zone.getSlaveCellNeighbors(54), [55, 53])
-
+# Global checks
test.assertEqual(DEFICO.getNumberOfContactZones(), 2)
test.assertEqual(DEFICO.getVerbosity(), 2)
test.assertEqual(DEFICO.getModel(), MODI)
-test.assertEqual(DEFICO.getMesh(), Mail)
+test.assertEqual(DEFICO.getMesh(), mesh)
test.assertFalse(DEFICO.hasFriction)
test.assertFalse(DEFICO.hasSmoothing)
-# Pairing checks
-
+# Some checks for the first zone
+zone = DEFICO.getContactZone(0)
+test.assertEqual(zone.getVerbosity(), 2)
+test.assertEqual(zone.getMesh(), mesh)
+
+# Some checks for geometric pairing
+pairGeom = zone.getMeshPairing()
+test.assertEqual(pairGeom.getVerbosity(), 2)
+test.assertEqual(pairGeom.getMesh(), mesh)
+test.assertEqual(pairGeom.getMasterCellsFromNode(19), [12, 13])
+test.assertEqual(pairGeom.getSlaveCellsFromNode(64), [61, 62])
+test.assertEqual(pairGeom.getMasterCellNeighbors(14), [13, 15])
+test.assertEqual(pairGeom.getSlaveCellNeighbors(54), [55, 53])
+
+# Create a displacement field
study = CA.PhysicalProblem(MODI, CHMAT, CARAMECA)
study.computeDOFNumbering()
dofNumbering = study.getDOFNumbering()
-
disp = CA.FieldOnNodesReal(dofNumbering)
disp.setValues(4)
-pair = CA.ContactPairing(DEFICO)
-pair.updateCoordinates(disp)
+
+# Contact pairing
+contPair = CA.ContactPairing(DEFICO)
+zone = DEFICO.getContactZone(0)
+test.assertEqual(zone.getVerbosity(), 2)
+test.assertEqual(zone.getMesh(), mesh)
+contPair.updateCoordinates(disp)
test.assertEqual(
- pair.getCoordinates().getValues()[:10], [54.0, 54.0, 4.0, 54.0, 4.0, 4.0, 4.0, 54.0, 4.0, 4.0]
+ contPair.getCoordinates().getValues()[:10],
+ [54.0, 54.0, 4.0, 54.0, 4.0, 4.0, 4.0, 54.0, 4.0, 4.0],
)
+# Checks on all zones
nb_zones = DEFICO.getNumberOfContactZones()
-for i in range(nb_zones):
- pair.computeZone(i)
-
+for iZone in range(nb_zones):
+ contPair.compute(iZone)
+ zone = DEFICO.getContactZone(iZone)
+ test.assertEqual(zone.getMesh(), mesh)
+ test.assertEqual(DEFICO.getVerbosity(), 2)
+# Some checks for the second zone
test.assertEqual(
- pair.getListOfPairsOfZone(1),
+ contPair.getListOfPairs(1),
[
(77, 30),
(78, 31),
@@ -157,19 +174,10 @@ test.assertEqual(
],
)
-test.assertEqual([pair.getNumberOfPairsOfZone(i) for i in range(nb_zones)], [26, 10])
-
-nbPairs = pair.getNumberOfPairs()
-test.assertEqual(nbPairs, sum(pair.getNumberOfPairsOfZone(i) for i in range(nb_zones)))
-
-
-# Testing AsterErrorMessage
-pair.clear()
-try:
- pair.getListOfPairsOfZone(0)
-except Exception as e:
- test.assertIn("List of pairs is empty or has an odd size", e.message)
+test.assertEqual([contPair.getNumberOfPairs(i) for i in range(nb_zones)], [26, 10])
+nbPairs = contPair.getNumberOfPairs()
+test.assertEqual(nbPairs, sum(contPair.getNumberOfPairs(i) for i in range(nb_zones)))
algo_cont = [CA.ContactAlgo.Lagrangian, CA.ContactAlgo.Nitsche]
vari_cont = [CA.ContactVariant.Empty, CA.ContactVariant.Fast]
@@ -185,7 +193,7 @@ for i in range(DEFICO.getNumberOfContactZones()):
test.assertFalse(zone.checkNormals)
test.assertEqual(zone.getModel(), MODI)
- test.assertEqual(zone.getMesh(), Mail)
+ test.assertEqual(zone.getMesh(), mesh)
contParam = zone.getContactParameter()
test.assertEqual(contParam.getAlgorithm(), algo_cont[i])
@@ -207,9 +215,6 @@ for i in range(DEFICO.getNumberOfContactZones()):
zone.setSlaveGroupOfCells("Group_4")
zone.setMasterGroupOfCells("Group_3")
-# zone1 = DEFICO.getContactZone(0)
-# test.assertEqual(zone1.getExcludedSlaveGroupOfCells(), ['Group_0'])
-
DEFICO.hasFriction = True
test.assertTrue(DEFICO.hasFriction)
DEFICO.hasSmoothing = False
diff --git a/astest/cont001b.py b/astest/cont001b.py
index 68f2e67a55b..f94e7555391 100644
--- a/astest/cont001b.py
+++ b/astest/cont001b.py
@@ -111,7 +111,7 @@
except CA.AsterError as err:
print(fmt_raison % str(err))
# on verifie que l'erreur fatale est bien celle que l'on attendait :
- if err.id_message == "CONTACT1_3":
+ if err.id_message == "CONTACT1_1":
is_ok = 1
test.assertEqual(is_ok, 1)
diff --git a/astest/cont001d.py b/astest/cont001d.py
index 2c28a229aff..06e0d4aa771 100644
--- a/astest/cont001d.py
+++ b/astest/cont001d.py
@@ -109,7 +109,7 @@
except CA.AsterError as err:
print(fmt_raison % str(err))
# on verifie que l'erreur fatale est bien celle que l'on attendait :
- if err.id_message == "CONTACT1_3":
+ if err.id_message == "CONTACT1_1":
is_ok = 1
test.assertEqual(is_ok, 1)
diff --git a/astest/cont001g.py b/astest/cont001g.py
index dea068c87b5..f07341767fc 100644
--- a/astest/cont001g.py
+++ b/astest/cont001g.py
@@ -22,7 +22,7 @@
from code_aster.Commands import *
from code_aster import CA
from code_aster.MacroCommands.defi_cont import DEFI_CONT
-from libaster import ContactPairing, ContactComputation
+from libaster import ContactPairing, ContactComputation, CoordinatesSpace
import numpy
@@ -32,18 +32,19 @@
test = CA.TestCase()
-Mail = LIRE_MAILLAGE(UNITE=20, FORMAT="MED")
+meshLine = LIRE_MAILLAGE(UNITE=20, FORMAT="MED")
-Mail = MODI_MAILLAGE(
- reuse=Mail, MAILLAGE=Mail, ORIE_PEAU=_F(GROUP_MA_PEAU=("CONT_HAUT", "CONT_BAS"))
+meshLine = MODI_MAILLAGE(
+ reuse=meshLine, MAILLAGE=meshLine, ORIE_PEAU=_F(GROUP_MA_PEAU=("CONT_HAUT", "CONT_BAS"))
)
-
-MODI = AFFE_MODELE(MAILLAGE=Mail, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="D_PLAN"))
+modelLine = AFFE_MODELE(
+ MAILLAGE=meshLine, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="D_PLAN")
+)
# Slave side - CONT_BAS
-DEFICO_BAS = DEFI_CONT(
- MODELE=MODI,
+contactLine = DEFI_CONT(
+ MODELE=modelLine,
INFO=2,
ZONE=(
_F(
@@ -57,101 +58,49 @@
)
# Pairing checks
-
-pair = ContactPairing(DEFICO_BAS)
+pair = ContactPairing(contactLine)
pair.compute()
-test.assertSequenceEqual(pair.getListOfPairsOfZone(0), [(18, 3), (18, 4), (19, 4), (19, 5)])
-ref = [
- [
- 0.5999999999999999,
- -0.7333333333333334,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- ],
- [
- -0.7333333333333334,
- -1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- ],
- [
- 1.0,
- -0.06666666666666687,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- ],
- [
- -0.06666666666666687,
- -1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- ],
-]
-
-test.assertEqual(len(pair.getSlaveIntersectionPoints(0)), 4)
-print(pair.getSlaveIntersectionPoints(0))
-test.assertSequenceEqual(pair.getSlaveIntersectionPoints(0), ref)
-
-
-MailQ = CREA_MAILLAGE(MAILLAGE=Mail, LINE_QUAD=_F(TOUT="OUI"))
-
-
-MODIQ = AFFE_MODELE(
- MAILLAGE=MailQ, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="D_PLAN")
+# One zone
+test.assertEqual(pair.getNumberOfZones(), 1)
+indexZone = 0
+
+# Get number of pairs on first zone
+test.assertEqual(pair.getNumberOfPairs(indexZone), 4)
+
+# Get list of pairs on first zone
+test.assertSequenceEqual(pair.getListOfPairs(indexZone), [(18, 3), (18, 4), (19, 4), (19, 5)])
+
+# Get intersection points: 4 paires de points d'intersection
+test.assertEqual(len(pair.getNumberOfIntersectionPoints(indexZone)), 4)
+
+# For each pair: two points of intersections
+iPair = 0
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair], 2)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 1], 2)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 2], 2)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 3], 2)
+
+# Values of intersections
+iPair = 0
+test.assertSequenceEqual(
+ pair.getIntersectionPoints(indexZone, CoordinatesSpace.Slave)[iPair],
+ (0.5999999999999999, 0.0, -0.7333333333333334, 0.0),
+)
+test.assertSequenceEqual(
+ pair.getIntersectionPoints(indexZone, CoordinatesSpace.Slave)[iPair + 1],
+ (-0.7333333333333334, 0.0, -1.0, 0.0),
+)
+
+meshQuad = CREA_MAILLAGE(MAILLAGE=meshLine, LINE_QUAD=_F(TOUT="OUI"))
+
+modelQuad = AFFE_MODELE(
+ MAILLAGE=meshQuad, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="D_PLAN")
)
# Slave side - CONT_BAS
-DEFICOQ_BAS = DEFI_CONT(
- MODELE=MODIQ,
+contactQuad = DEFI_CONT(
+ MODELE=modelQuad,
INFO=2,
ZONE=(
_F(
@@ -165,90 +114,39 @@
)
# Pairing checks
-
-pair = ContactPairing(DEFICOQ_BAS)
+pair = ContactPairing(contactQuad)
pair.compute()
+# One zone
+test.assertEqual(pair.getNumberOfZones(), 1)
+indexZone = 0
+
+# Get number of pairs on first zone
+test.assertEqual(pair.getNumberOfPairs(indexZone), 4)
+
+# Get list of pairs on first zone
+test.assertSequenceEqual(pair.getListOfPairs(indexZone), [(18, 3), (18, 4), (19, 4), (19, 5)])
+
+# Get intersection points
+test.assertEqual(len(pair.getNumberOfIntersectionPoints(indexZone)), 4)
+
+# For each pair: two points of intersections
+iPair = 0
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair], 2)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 1], 2)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 2], 2)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 3], 2)
+
+# Values of intersections
+iPair = 0
+test.assertSequenceEqual(
+ pair.getIntersectionPoints(indexZone, CoordinatesSpace.Slave)[iPair],
+ (0.5999999999999999, 0.0, -0.7333333333333334, 0.0),
+)
+test.assertSequenceEqual(
+ pair.getIntersectionPoints(indexZone, CoordinatesSpace.Slave)[iPair + 1],
+ (-0.7333333333333334, 0.0, -1.0, 0.0),
+)
-test.assertSequenceEqual(pair.getListOfPairsOfZone(0), [(18, 3), (18, 4), (19, 4), (19, 5)])
-ref = [
- [
- 0.5999999999999999,
- -0.7333333333333334,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- ],
- [
- -0.7333333333333334,
- -1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- ],
- [
- 1.0,
- -0.06666666666666687,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- ],
- [
- -0.06666666666666687,
- -1.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- ],
-]
-
-test.assertEqual(len(pair.getSlaveIntersectionPoints(0)), 4)
-test.assertEqual(len(pair.getSlaveIntersectionPoints(0)[0]), 16)
-print(pair.getSlaveIntersectionPoints(0))
-test.assertSequenceEqual(pair.getSlaveIntersectionPoints(0), ref)
FIN()
diff --git a/astest/cont001i.py b/astest/cont001i.py
index 153e09df377..96034472deb 100644
--- a/astest/cont001i.py
+++ b/astest/cont001i.py
@@ -22,31 +22,29 @@
from code_aster.Commands import *
from code_aster import CA
from code_aster.MacroCommands.defi_cont import DEFI_CONT
-from libaster import ContactPairing, ContactComputation
+from libaster import ContactPairing, ContactComputation, CoordinatesSpace
import numpy
DEBUT(
- CODE=_F(NIV_PUB_WEB="INTERNET"),
- ERREUR=_F(ALARME="EXCEPTION"),
- # DEBUG=_F(SDVERI='OUI',),
- INFO=1,
+ CODE=_F(NIV_PUB_WEB="INTERNET"), ERREUR=_F(ALARME="EXCEPTION"), DEBUG=_F(SDVERI="NON"), INFO=1
)
test = CA.TestCase()
-Mail = LIRE_MAILLAGE(UNITE=20, FORMAT="MED")
+meshLine = LIRE_MAILLAGE(UNITE=20, FORMAT="MED")
-Mail = MODI_MAILLAGE(
- reuse=Mail, MAILLAGE=Mail, ORIE_PEAU=_F(GROUP_MA_PEAU=("CONT_HAUT", "CONT_BAS"))
+meshLine = MODI_MAILLAGE(
+ reuse=meshLine, MAILLAGE=meshLine, ORIE_PEAU=_F(GROUP_MA_PEAU=("CONT_HAUT", "CONT_BAS"))
)
-
-MODI = AFFE_MODELE(MAILLAGE=Mail, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="3D"))
+modelLine = AFFE_MODELE(
+ MAILLAGE=meshLine, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="3D")
+)
# Slave side - CONT_BAS
-DEFICO_BAS = DEFI_CONT(
- MODELE=MODI,
+contactLine = DEFI_CONT(
+ MODELE=modelLine,
INFO=2,
ZONE=(
_F(
@@ -60,37 +58,54 @@
)
# Pairing checks
-
-pair = ContactPairing(DEFICO_BAS)
+pair = ContactPairing(contactLine)
+pair.setVerbosity(1)
pair.compute()
+# One zone
+test.assertEqual(pair.getNumberOfZones(), 1)
+indexZone = 0
+
+# Get number of pairs on first zone
+test.assertEqual(pair.getNumberOfPairs(indexZone), 9)
+
+# Get list of pairs on first zone
test.assertSequenceEqual(
- pair.getListOfPairsOfZone(0),
+ pair.getListOfPairs(indexZone),
[(68, 88), (68, 90), (70, 88), (69, 90), (69, 91), (69, 88), (69, 89), (71, 88), (71, 89)],
)
-ref = [
- [1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0, 1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0, 1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0, 1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0, 1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
-]
-test.assertEqual(len(pair.getSlaveIntersectionPoints(0)), 9)
-print(pair.getSlaveIntersectionPoints(0))
-test.assertSequenceEqual(pair.getSlaveIntersectionPoints(0), ref)
-
-MailQ = CREA_MAILLAGE(MAILLAGE=Mail, LINE_QUAD=_F(TOUT="OUI"))
-
-
-MODIQ = AFFE_MODELE(MAILLAGE=MailQ, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="3D"))
+
+# Get intersection points: 9 paires de points d'intersection
+test.assertEqual(len(pair.getNumberOfIntersectionPoints(indexZone)), 9)
+
+# For each pair: 4 points of intersections
+iPair = 0
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair], 4)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 1], 4)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 2], 4)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 3], 4)
+
+# Values of intersections
+iPair = 0
+test.assertSequenceEqual(
+ pair.getIntersectionPoints(indexZone, CoordinatesSpace.Slave)[iPair],
+ (1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0),
+)
+iPair = 1
+test.assertSequenceEqual(
+ pair.getIntersectionPoints(indexZone, CoordinatesSpace.Slave)[iPair],
+ (0.0, 0.0, 0.0, 1.0, -1.0, 1.0, -1.0, 0.0),
+)
+
+meshQuad = CREA_MAILLAGE(MAILLAGE=meshLine, LINE_QUAD=_F(TOUT="OUI"))
+
+modelQuad = AFFE_MODELE(
+ MAILLAGE=meshQuad, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="3D")
+)
# Slave side - CONT_BAS
-DEFICOQ_BAS = DEFI_CONT(
- MODELE=MODIQ,
+contactQuad = DEFI_CONT(
+ MODELE=modelQuad,
INFO=2,
ZONE=(
_F(
@@ -104,29 +119,38 @@
)
# Pairing checks
-
-pair = ContactPairing(DEFICOQ_BAS)
+pair = ContactPairing(contactQuad)
+pair.setVerbosity(1)
pair.compute()
+# One zone
+test.assertEqual(pair.getNumberOfZones(), 1)
+indexZone = 0
+
+# Get number of pairs on first zone
+test.assertEqual(pair.getNumberOfPairs(indexZone), 9)
+# Get list of pairs on first zone
test.assertSequenceEqual(
- pair.getListOfPairsOfZone(0),
+ pair.getListOfPairs(indexZone),
[(88, 68), (88, 70), (88, 69), (88, 71), (90, 69), (90, 68), (89, 71), (89, 69), (91, 69)],
)
-ref = [
- [1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0, 1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, 0.0, 0.0, 1.0, -1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
- [0.0, -1.0, 0.0, 0.0, -1.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
-]
-test.assertEqual(len(pair.getSlaveIntersectionPoints(0)), 9)
-test.assertEqual(len(pair.getSlaveIntersectionPoints(0)[0]), 16)
-print(pair.getSlaveIntersectionPoints(0))
-test.assertSequenceEqual(pair.getSlaveIntersectionPoints(0), ref)
+
+# Get intersection points: 4 paires de points d'intersection
+test.assertEqual(len(pair.getNumberOfIntersectionPoints(indexZone)), 9)
+
+# For each pair: two points of intersections
+iPair = 0
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair], 4)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 1], 4)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 2], 4)
+test.assertEqual(pair.getNumberOfIntersectionPoints(indexZone)[iPair + 3], 4)
+
+# Values of intersections
+iPair = 0
+test.assertSequenceEqual(
+ pair.getIntersectionPoints(indexZone, CoordinatesSpace.Slave)[iPair],
+ (1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0),
+)
FIN()
diff --git a/astest/cont101a.export b/astest/cont101a.export
new file mode 100644
index 00000000000..20da60ed5ea
--- /dev/null
+++ b/astest/cont101a.export
@@ -0,0 +1,9 @@
+P time_limit 30
+P memory_limit 524
+P ncpus 1
+P mpi_nbcpu 1
+P mpi_nbnoeud 1
+P testlist submit verification sequential
+
+F comm cont101a.py D 1
+F mmed cont101a.mmed D 20
diff --git a/astest/cont101a.mmed b/astest/cont101a.mmed
new file mode 100644
index 00000000000..a44253d332d
Binary files /dev/null and b/astest/cont101a.mmed differ
diff --git a/astest/cont101a.py b/astest/cont101a.py
new file mode 100644
index 00000000000..b422858f765
--- /dev/null
+++ b/astest/cont101a.py
@@ -0,0 +1,266 @@
+# coding=utf-8
+# --------------------------------------------------------------------
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+# This file is part of code_aster.
+#
+# code_aster is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# code_aster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with code_aster. If not, see .
+# --------------------------------------------------------------------
+
+#
+
+from code_aster.Commands import *
+from code_aster import CA
+from enum import Enum
+from code_aster.MacroCommands.defi_cont import DEFI_CONT
+from libaster import ContactPairing, ContactComputation, PairingMethod
+import numpy
+
+
+DEBUT(
+ CODE=_F(NIV_PUB_WEB="INTERNET"),
+ ERREUR=_F(ALARME="EXCEPTION"),
+ # DEBUG=_F(SDVERI='OUI',),
+ INFO=1,
+)
+
+test = CA.TestCase()
+
+Mail = LIRE_MAILLAGE(UNITE=20, FORMAT="MED", INFO=2)
+
+Mail = MODI_MAILLAGE(
+ reuse=Mail, MAILLAGE=Mail, ORIE_PEAU=_F(GROUP_MA_PEAU=("CONT_HAUT", "CONT_BAS"))
+)
+
+MODI = AFFE_MODELE(MAILLAGE=Mail, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="3D"))
+
+
+# Generate pairs
+meshPair = CA.MeshPairing(Mail)
+meshPair.setVerbosity(1)
+meshPair.setPair("CONT_BAS", "CONT_HAUT")
+meshPair.setMethod(PairingMethod.Fast)
+meshPair.compute()
+
+# Get pairs
+nbPairs = meshPair.getNumberOfPairs()
+listPairs = meshPair.getListOfPairs()
+
+# Some checks
+test.assertSequenceEqual(
+ listPairs,
+ [
+ (141, 260),
+ (141, 265),
+ (144, 260),
+ (144, 255),
+ (144, 250),
+ (142, 265),
+ (142, 266),
+ (142, 260),
+ (142, 267),
+ (142, 261),
+ (142, 262),
+ (147, 250),
+ (145, 250),
+ (145, 255),
+ (145, 251),
+ (145, 260),
+ (145, 256),
+ (145, 252),
+ (145, 261),
+ (145, 257),
+ (145, 262),
+ (143, 262),
+ (143, 267),
+ (143, 263),
+ (143, 268),
+ (148, 250),
+ (148, 251),
+ (148, 252),
+ (146, 262),
+ (146, 263),
+ (146, 257),
+ (146, 258),
+ (146, 252),
+ (146, 253),
+ (149, 252),
+ (149, 253),
+ ],
+)
+
+# Generate pairs
+meshPair = CA.MeshPairing(Mail)
+meshPair.setVerbosity(1)
+meshPair.setPair("CONT_BAS", "CONT_HAUT")
+meshPair.setMethod(PairingMethod.Legacy)
+meshPair.compute()
+
+# Get pairs
+nbPairs = meshPair.getNumberOfPairs()
+listPairs = meshPair.getListOfPairs()
+
+print("Nb pairs: ", nbPairs)
+print("List pairs: ", listPairs)
+
+# Some checks
+test.assertSequenceEqual(
+ listPairs,
+ [
+ (141, 260),
+ (141, 265),
+ (144, 260),
+ (144, 255),
+ (144, 250),
+ (142, 265),
+ (142, 266),
+ (142, 260),
+ (142, 267),
+ (142, 261),
+ (142, 262),
+ (147, 250),
+ (145, 250),
+ (145, 255),
+ (145, 251),
+ (145, 260),
+ (145, 256),
+ (145, 252),
+ (145, 261),
+ (145, 257),
+ (145, 262),
+ (143, 262),
+ (143, 267),
+ (143, 263),
+ (143, 268),
+ (148, 250),
+ (148, 251),
+ (148, 252),
+ (146, 262),
+ (146, 263),
+ (146, 257),
+ (146, 258),
+ (146, 252),
+ (146, 253),
+ (149, 252),
+ (149, 253),
+ ],
+)
+
+# Generate pairs
+meshPair = CA.MeshPairing(Mail)
+meshPair.setVerbosity(1)
+meshPair.setPair("CONT_BAS", "CONT_HAUT")
+meshPair.setMethod(PairingMethod.BrutForce)
+meshPair.compute()
+
+# Get pairs
+nbPairs = meshPair.getNumberOfPairs()
+listPairs = meshPair.getListOfPairs()
+
+test.assertSequenceEqual(
+ listPairs,
+ [
+ (141, 260),
+ (141, 265),
+ (142, 260),
+ (142, 261),
+ (142, 262),
+ (142, 265),
+ (142, 266),
+ (142, 267),
+ (143, 262),
+ (143, 263),
+ (143, 267),
+ (143, 268),
+ (144, 250),
+ (144, 255),
+ (144, 260),
+ (145, 250),
+ (145, 251),
+ (145, 252),
+ (145, 255),
+ (145, 256),
+ (145, 257),
+ (145, 260),
+ (145, 261),
+ (145, 262),
+ (146, 252),
+ (146, 253),
+ (146, 257),
+ (146, 258),
+ (146, 262),
+ (146, 263),
+ (147, 250),
+ (148, 250),
+ (148, 251),
+ (148, 252),
+ (149, 252),
+ (149, 253),
+ ],
+)
+
+# Generate pairs
+meshPair = CA.MeshPairing(Mail)
+meshPair.setVerbosity(1)
+meshPair.setPair("CONT_HAUT", "CONT_BAS")
+# meshPair.setMethod("NEW")
+meshPair.compute()
+
+# Get pairs
+nbPairs = meshPair.getNumberOfPairs()
+listPairs = meshPair.getListOfPairs()
+
+# Some checks
+test.assertSequenceEqual(
+ listPairs,
+ [
+ (250, 144),
+ (250, 147),
+ (250, 145),
+ (250, 148),
+ (255, 145),
+ (255, 144),
+ (251, 148),
+ (251, 145),
+ (260, 144),
+ (260, 145),
+ (260, 141),
+ (260, 142),
+ (256, 145),
+ (252, 145),
+ (252, 148),
+ (252, 146),
+ (252, 149),
+ (265, 142),
+ (265, 141),
+ (261, 142),
+ (261, 145),
+ (257, 145),
+ (257, 146),
+ (253, 149),
+ (253, 146),
+ (266, 142),
+ (262, 145),
+ (262, 146),
+ (262, 142),
+ (262, 143),
+ (258, 146),
+ (267, 142),
+ (267, 143),
+ (263, 143),
+ (263, 146),
+ (268, 143),
+ ],
+)
+
+FIN()
diff --git a/astest/cont101b.export b/astest/cont101b.export
new file mode 100644
index 00000000000..c327d80bda6
--- /dev/null
+++ b/astest/cont101b.export
@@ -0,0 +1,9 @@
+P time_limit 30
+P memory_limit 524
+P ncpus 1
+P mpi_nbcpu 1
+P mpi_nbnoeud 1
+P testlist submit verification sequential
+
+F comm cont101b.py D 1
+F mmed cont101b.mmed D 20
diff --git a/astest/cont101b.mmed b/astest/cont101b.mmed
new file mode 100644
index 00000000000..0c50bd91f29
Binary files /dev/null and b/astest/cont101b.mmed differ
diff --git a/astest/cont101b.py b/astest/cont101b.py
new file mode 100644
index 00000000000..9bb6a9ce7bb
--- /dev/null
+++ b/astest/cont101b.py
@@ -0,0 +1,235 @@
+# coding=utf-8
+# --------------------------------------------------------------------
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+# This file is part of code_aster.
+#
+# code_aster is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# code_aster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with code_aster. If not, see .
+# --------------------------------------------------------------------
+
+#
+
+from code_aster.Commands import *
+from code_aster import CA
+from code_aster.MacroCommands.defi_cont import DEFI_CONT
+from libaster import ContactPairing, ContactComputation, PairingMethod
+import numpy
+
+
+DEBUT(
+ CODE=_F(NIV_PUB_WEB="INTERNET"),
+ ERREUR=_F(ALARME="EXCEPTION"),
+ # DEBUG=_F(SDVERI='OUI',),
+ INFO=1,
+)
+
+test = CA.TestCase()
+
+Mail = LIRE_MAILLAGE(UNITE=20, FORMAT="MED", INFO=2)
+
+Mail = MODI_MAILLAGE(
+ reuse=Mail, MAILLAGE=Mail, ORIE_PEAU=_F(GROUP_MA_PEAU=("CONT_HAUT", "CONT_BAS"))
+)
+
+MODI = AFFE_MODELE(MAILLAGE=Mail, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="3D"))
+
+# Generate pairs
+meshPair = CA.MeshPairing(Mail)
+meshPair.setVerbosity(2)
+meshPair.setPair("CONT_BAS", "CONT_HAUT")
+meshPair.setMethod(PairingMethod.Fast)
+meshPair.compute()
+
+# Get pairs
+nbPairs = meshPair.getNumberOfPairs()
+listPairs = meshPair.getListOfPairs()
+
+# Get quadrature points
+indexPair = 4
+quadPoin = meshPair.getQuadraturePoints(indexPair)
+print(" => Coordinates of quadrature points (global space):", quadPoin)
+
+# Some checks
+test.assertSequenceEqual(
+ listPairs,
+ [
+ (465, 314),
+ (465, 316),
+ (465, 332),
+ (465, 331),
+ (465, 330),
+ (468, 330),
+ (468, 313),
+ (468, 331),
+ (468, 328),
+ (468, 312),
+ (466, 330),
+ (466, 331),
+ (466, 360),
+ (466, 332),
+ (466, 362),
+ (466, 314),
+ (466, 344),
+ (466, 364),
+ (466, 316),
+ (466, 345),
+ (466, 358),
+ (466, 335),
+ (466, 357),
+ (471, 312),
+ (469, 312),
+ (469, 328),
+ (469, 313),
+ (469, 352),
+ (469, 330),
+ (469, 341),
+ (469, 356),
+ (469, 360),
+ (469, 343),
+ (469, 347),
+ (469, 362),
+ (469, 364),
+ (467, 357),
+ (467, 359),
+ (467, 358),
+ (467, 355),
+ (467, 365),
+ (467, 364),
+ (467, 354),
+ (467, 363),
+ (467, 351),
+ (467, 361),
+ (467, 353),
+ (472, 312),
+ (472, 328),
+ (472, 352),
+ (472, 341),
+ (472, 343),
+ (472, 327),
+ (470, 364),
+ (470, 362),
+ (470, 365),
+ (470, 360),
+ (470, 363),
+ (470, 356),
+ (470, 350),
+ (470, 361),
+ (470, 347),
+ (470, 348),
+ (470, 353),
+ (470, 343),
+ (470, 333),
+ (470, 349),
+ (470, 327),
+ (470, 326),
+ (473, 327),
+ (473, 343),
+ (473, 333),
+ (473, 326),
+ ],
+)
+
+
+# Generate pairs
+meshPair = CA.MeshPairing(Mail)
+meshPair.setVerbosity(2)
+meshPair.setPair("CONT_HAUT", "CONT_BAS")
+meshPair.setMethod(PairingMethod.Fast)
+meshPair.compute()
+
+# Get pairs
+nbPairs = meshPair.getNumberOfPairs()
+listPairs = meshPair.getListOfPairs()
+
+# Some checks
+test.assertSequenceEqual(
+ listPairs,
+ [
+ (312, 468),
+ (312, 471),
+ (312, 469),
+ (312, 472),
+ (328, 472),
+ (328, 469),
+ (328, 468),
+ (313, 468),
+ (313, 469),
+ (352, 469),
+ (352, 472),
+ (330, 469),
+ (330, 468),
+ (330, 466),
+ (330, 465),
+ (341, 472),
+ (341, 469),
+ (356, 469),
+ (356, 470),
+ (331, 465),
+ (331, 468),
+ (331, 466),
+ (360, 466),
+ (360, 469),
+ (360, 470),
+ (343, 469),
+ (343, 472),
+ (343, 470),
+ (343, 473),
+ (347, 470),
+ (347, 469),
+ (332, 466),
+ (332, 465),
+ (362, 470),
+ (362, 469),
+ (362, 466),
+ (327, 473),
+ (327, 472),
+ (327, 470),
+ (350, 470),
+ (314, 465),
+ (314, 466),
+ (344, 466),
+ (364, 466),
+ (364, 469),
+ (364, 467),
+ (364, 470),
+ (333, 470),
+ (333, 473),
+ (363, 470),
+ (363, 467),
+ (348, 470),
+ (316, 466),
+ (316, 465),
+ (345, 466),
+ (358, 467),
+ (358, 466),
+ (365, 470),
+ (365, 467),
+ (326, 473),
+ (326, 470),
+ (361, 467),
+ (361, 470),
+ (349, 470),
+ (335, 466),
+ (357, 466),
+ (357, 467),
+ (359, 467),
+ (351, 467),
+ (353, 470),
+ (353, 467),
+ (355, 467),
+ (354, 467),
+ ],
+)
+
+
+FIN()
diff --git a/astest/cont101c.export b/astest/cont101c.export
new file mode 100644
index 00000000000..1b77e441637
--- /dev/null
+++ b/astest/cont101c.export
@@ -0,0 +1,9 @@
+P time_limit 30
+P memory_limit 524
+P ncpus 1
+P mpi_nbcpu 1
+P mpi_nbnoeud 1
+P testlist submit verification sequential
+
+F comm cont101c.py D 1
+F mmed cont101c.mmed D 20
diff --git a/astest/cont101c.mmed b/astest/cont101c.mmed
new file mode 100644
index 00000000000..f055d62eb06
Binary files /dev/null and b/astest/cont101c.mmed differ
diff --git a/astest/cont101c.py b/astest/cont101c.py
new file mode 100644
index 00000000000..c366ef920e9
--- /dev/null
+++ b/astest/cont101c.py
@@ -0,0 +1,255 @@
+# coding=utf-8
+# --------------------------------------------------------------------
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+# This file is part of code_aster.
+#
+# code_aster is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# code_aster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with code_aster. If not, see .
+# --------------------------------------------------------------------
+
+# -- Lines for dummy test and visualisation test
+path_repo_save = (
+ "/home/i48378/Documents/workspace/sandbox/sandbox-contact-mec-pairing-tests/cont101c"
+)
+import os.path as osp
+import numpy as np
+
+# case - a (Slave side = CONT_BAS)
+path_pairs_a = osp.join(path_repo_save, "case_a/listOfPairs.npy")
+path_intepoints_a = osp.join(path_repo_save, "case_a/intersectionPoints.npy")
+path_quadpoints_a = osp.join(path_repo_save, "case_a/quadraturePoints.npy")
+# case - b (Slave side = CONT_HAUT)
+path_pairs_b = osp.join(path_repo_save, "case_b/listOfPairs.npy")
+path_intepoints_b = osp.join(path_repo_save, "case_b/intersectionPoints.npy")
+path_quadpoints_b = osp.join(path_repo_save, "case_b/quadraturePoints.npy")
+save_data = True
+
+# -- Core of the test case
+from code_aster.Commands import *
+from code_aster import CA
+from code_aster.MacroCommands.defi_cont import DEFI_CONT
+from libaster import ContactPairing, ContactComputation, PairingMethod
+import numpy
+
+
+DEBUT(
+ CODE=_F(NIV_PUB_WEB="INTERNET"),
+ ERREUR=_F(ALARME="EXCEPTION"),
+ # DEBUG=_F(SDVERI='OUI',),
+ INFO=1,
+)
+
+test = CA.TestCase()
+
+Mail = LIRE_MAILLAGE(UNITE=20, FORMAT="MED", INFO=2)
+
+Mail = MODI_MAILLAGE(
+ reuse=Mail, MAILLAGE=Mail, ORIE_PEAU=_F(GROUP_MA_PEAU=("CONT_HAUT", "CONT_BAS"))
+)
+
+MODI = AFFE_MODELE(MAILLAGE=Mail, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="3D"))
+
+# # Slave side - CONT_BAS
+# DEFICO_BAS = DEFI_CONT(
+# MODELE=MODI,
+# INFO=2,
+# ZONE=(
+# _F(
+# APPARIEMENT="MORTAR",
+# GROUP_MA_MAIT="CONT_HAUT",
+# GROUP_MA_ESCL="CONT_BAS",
+# ALGO_CONT="LAGRANGIEN",
+# CONTACT_INIT="OUI",
+# ),
+# ),
+# )
+
+# # Pairing checks
+# pair = ContactPairing(DEFICO_BAS)
+# pair.compute()
+
+# # some checks for the zone 0:
+# zone = DEFICO_BAS.getContactZone(0)
+# meshPair = zone.getMeshPairing()
+# listPairs_zone = meshPair.getListOfPairs()
+
+# Generate pairs
+meshPair = CA.MeshPairing(Mail)
+meshPair.setVerbosity(2)
+meshPair.setPair("CONT_BAS", "CONT_HAUT")
+meshPair.setMethod(PairingMethod.Fast)
+meshPair.compute()
+
+# Get pairs
+nbPairs = meshPair.getNumberOfPairs()
+listPairs = meshPair.getListOfPairs()
+
+print("Nb pairs: ", nbPairs)
+print("List pairs: ", listPairs)
+
+
+# Some checks
+test.assertSequenceEqual(
+ listPairs,
+ [
+ (186, 319),
+ (198, 319),
+ (198, 314),
+ (198, 309),
+ (187, 309),
+ (202, 309),
+ (202, 314),
+ (202, 310),
+ (202, 319),
+ (202, 315),
+ (202, 320),
+ (202, 316),
+ (189, 309),
+ (189, 304),
+ (203, 316),
+ (203, 315),
+ (203, 311),
+ (203, 310),
+ (203, 306),
+ (203, 309),
+ (203, 305),
+ (197, 316),
+ (197, 315),
+ (197, 321),
+ (197, 320),
+ (197, 319),
+ (188, 304),
+ (201, 304),
+ (201, 309),
+ (201, 305),
+ (201, 310),
+ (201, 306),
+ (195, 306),
+ (195, 311),
+ (195, 316),
+ (195, 312),
+ (195, 317),
+ (196, 321),
+ (196, 322),
+ (196, 316),
+ (190, 304),
+ (200, 306),
+ (200, 305),
+ (200, 304),
+ (193, 317),
+ (193, 312),
+ (193, 311),
+ (193, 307),
+ (193, 306),
+ (194, 317),
+ (194, 316),
+ (194, 322),
+ (194, 321),
+ (191, 304),
+ (199, 306),
+ (199, 307),
+ (192, 307),
+ ],
+)
+
+intePoints = meshPair.getIntersectionPoints(0)
+
+print("intePoints: ", intePoints)
+
+test.assertAlmostEqual(intePoints[0][0], 50.0)
+test.assertAlmostEqual(intePoints[0][1], 183.3333333333333)
+test.assertAlmostEqual(intePoints[0][2], 200.0)
+
+
+# if save_data:
+# np.save(path_pairs_a, listPairs)
+# intePointsList = []
+# quadPointsList = []
+# # - Loop over the pairs
+# for index_pair in range(nbPairs):
+# # - Store and save intersection points
+# IntePoints = meshPair.getIntersectionPoints(index_pair)
+# intePts_current = [tuple(intePt) for intePt in IntePoints]
+# intePointsList.append(intePts_current)
+# # - Store and save integration points
+# quadPoints = meshPair.getQuadraturePoints(index_pair)
+# quadPts_current = [tuple(quaPt) for quaPt in quadPoints]
+# quadPointsList.append(quadPts_current)
+# # - Save data
+# np.save(path_intepoints_a, intePointsList)
+# np.save(path_quadpoints_a, quadPointsList)
+
+# # Slave side - CONT_BAS
+# DEFICO_HAUT = DEFI_CONT(
+# MODELE=MODI,
+# INFO=2,
+# ZONE=(
+# _F(
+# APPARIEMENT="MORTAR",
+# GROUP_MA_MAIT="CONT_BAS",
+# GROUP_MA_ESCL="CONT_HAUT",
+# ALGO_CONT="LAGRANGIEN",
+# CONTACT_INIT="OUI",
+# ),
+# ),
+# )
+
+# # Pairing checks
+# pair = ContactPairing(DEFICO_HAUT)
+# pair.compute()
+
+# # some checks for the zone 0:
+# zone = DEFICO_HAUT.getContactZone(0)
+# meshPair = zone.getMeshPairing()
+# listPairs_zone = meshPair.getListOfPairs()
+
+# # Generate pairs
+# meshPair = CA.MeshPairing(Mail)
+# meshPair.setVerbosity(2)
+# meshPair.setPair("CONT_HAUT", "CONT_BAS")
+# meshPair.setMethod("NEW")
+# meshPair.compute()
+
+# # Get pairs
+# nbPairs = meshPair.getNumberOfPairs()
+# listPairs = meshPair.getListOfPairs()
+
+# # Some checks
+# test.assertSequenceEqual(listPairs,
+# [(304, 188), (304, 190), (304, 189), (304, 191), (304, 201), (304, 200), (309, 201), (309, 189), (309, 203), \
+# (309, 187), (309, 202), (309, 198), (305, 200), (305, 201), (305, 203), (314, 198), (314, 202), (310, 202), \
+# (310, 203), (310, 201), (306, 203), (306, 201), (306, 195), (306, 200), (306, 193), (306, 199), (319, 202), \
+# (319, 198), (319, 197), (319, 186), (315, 202), (315, 203), (315, 197), (311, 203), (311, 195), (311, 193), \
+# (307, 199), (307, 192), (307, 193), (320, 197), (320, 202), (316, 197), (316, 202), (316, 196), (316, 203), \
+# (316, 194), (316, 195), (312, 193), (312, 195), (321, 197), (321, 196), (321, 194), (317, 195), (317, 193), \
+# (317, 194), (322, 194), (322, 196)])
+
+# if save_data:
+# intePointsList = []
+# quadPointsList = []
+# # - Loop over the pairs
+# for index_pair in range(nbPairs):
+# # - Store and save intersection points
+# IntePoints = meshPair.getIntersectionPoints(index_pair)
+# intePts_current = [tuple(intePt) for intePt in IntePoints]
+# intePointsList.append(intePts_current)
+# # - Store and save integration points
+# quadPoints = meshPair.getQuadraturePoints(indexPair)
+# quadPts_current = [tuple(quaPt) for quaPt in quadPoints]
+# quadPointsList.append(quadPts_current)
+# # - Save data
+# np.save(path_intepoints_b, intePointsList)
+# np.save(path_quadpoints_b, quadPointsList)
+
+
+FIN()
diff --git a/astest/cont103b.export b/astest/cont103b.export
new file mode 100644
index 00000000000..00abc192886
--- /dev/null
+++ b/astest/cont103b.export
@@ -0,0 +1,9 @@
+P time_limit 30
+P memory_limit 524
+P ncpus 1
+P mpi_nbcpu 1
+P mpi_nbnoeud 1
+P testlist submit verification sequential
+
+F comm cont103b.py D 1
+F mmed cont103b.mmed D 20
diff --git a/astest/cont103b.mmed b/astest/cont103b.mmed
new file mode 100644
index 00000000000..7492568cf1a
Binary files /dev/null and b/astest/cont103b.mmed differ
diff --git a/astest/cont103b.py b/astest/cont103b.py
new file mode 100644
index 00000000000..6fa4f10c8e8
--- /dev/null
+++ b/astest/cont103b.py
@@ -0,0 +1,86 @@
+# coding=utf-8
+# --------------------------------------------------------------------
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+# This file is part of code_aster.
+#
+# code_aster is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# code_aster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with code_aster. If not, see .
+# --------------------------------------------------------------------
+
+from code_aster.Commands import *
+from code_aster import CA
+from code_aster.MacroCommands.defi_cont import DEFI_CONT
+from libaster import ContactPairing, ContactComputation, PairingMethod
+import numpy
+
+import os.path as osp
+import time
+import numpy as np
+
+
+# -------------------------------------
+# - Main
+# -------------------------------------
+DEBUT(CODE=_F(NIV_PUB_WEB="INTERNET"), DEBUG=_F(SDVERI="OUI"), INFO=1)
+
+test = CA.TestCase()
+
+Mail = LIRE_MAILLAGE(UNITE=20, FORMAT="MED")
+
+Mail = MODI_MAILLAGE(
+ reuse=Mail, MAILLAGE=Mail, ORIE_PEAU=_F(GROUP_MA_PEAU=("CONT_HAUT", "CONT_BAS"))
+)
+
+MAT = DEFI_MATERIAU(ELAS=_F(E=20000, NU=0.3, ALPHA=0.01))
+
+CHMAT = AFFE_MATERIAU(MAILLAGE=Mail, AFFE=_F(TOUT="OUI", MATER=MAT))
+
+MODI = AFFE_MODELE(MAILLAGE=Mail, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="D_PLAN"))
+
+# -------------------------------------
+# - Slave side - CONT_BAS
+# -------------------------------------
+## -- OLD PAIRING METHOD
+# - Generate pairs
+meshPair_old = CA.MeshPairing(Mail)
+meshPair_old.setVerbosity(2)
+meshPair_old.setPair("CONT_BAS", "CONT_HAUT")
+meshPair_old.setMethod(PairingMethod.Legacy)
+
+t_0_old = time.time()
+meshPair_old.compute()
+dur_old = time.time() - t_0_old
+
+# - Get pairs
+nbPairs_old = meshPair_old.getNumberOfPairs()
+listPairs_old = meshPair_old.getListOfPairs()
+
+# -- FAST PAIRING METHOD
+# - Generate pairs
+meshPair_fast = CA.MeshPairing(Mail)
+meshPair_fast.setVerbosity(2)
+meshPair_fast.setPair("CONT_BAS", "CONT_HAUT")
+meshPair_fast.setMethod(PairingMethod.BrutForce)
+
+t_0_fast = time.time()
+meshPair_fast.compute()
+dur_fast = time.time() - t_0_fast
+
+# - Get pairs
+nbPairs_fast = meshPair_fast.getNumberOfPairs()
+listPairs_fast = meshPair_fast.getListOfPairs()
+
+test.assertEqual(nbPairs_fast, nbPairs_old)
+
+
+FIN()
diff --git a/astest/vocab01a.34 b/astest/vocab01a.34
index 6827e17dcdf..981935ed34b 100644
--- a/astest/vocab01a.34
+++ b/astest/vocab01a.34
@@ -492,6 +492,7 @@ A_T_D_L
A_T_D_N
A_T_L
A_T_N
+ArrheniusIndex
B
B1
B2
@@ -538,6 +539,8 @@ BETA_PIC
BETA_REEL
BETA_ULT
BETON
+BETON_AGEING
+BETON_AGEING_FO
BETON_BURGER
BETON_BURGER_FO
BETON_DESORP
@@ -1298,6 +1301,7 @@ C_S_VP
C_TZTZ
C_VOLU
Cohesion
+ConcreteInitTime
CritStateSlope
D
D0
@@ -1702,6 +1706,7 @@ D_SIGM_EPSI_NORM
D_VAN_A
D_VAN_B
D_VISC_TEMP
+DessiccationModulus
DilatancyAngle
E
E1
@@ -3427,6 +3432,7 @@ K_T_D_L
K_T_D_N
K_T_L
K_T_N
+KelvinIndex
L
L2
LA2_FLI
@@ -4071,6 +4077,8 @@ M_T_L
M_T_N
M_ULT
M_ZIRC
+MaxwellDevModulus
+MaxwellSphModulus
MetaAcierEPIL_PT
MetaAcierEPIL_PT_FO
MinCritPress
@@ -5332,6 +5340,7 @@ R_X2
R_X5
RefeConsPress
ReferencePressure
+ReferenceTemperature
S
SA
SANDWICH
@@ -6416,6 +6425,10 @@ VZ
V_1
V_2
V_BETON_GRANGER
+VoigtDevModulus
+VoigtDevViscosity
+VoigtSphModulus
+VoigtSphViscosity
W
WAECKEL
WEIBULL
diff --git a/astest/wtnv104a.comm b/astest/wtnv104a.comm
new file mode 100644
index 00000000000..1b36a0128c9
--- /dev/null
+++ b/astest/wtnv104a.comm
@@ -0,0 +1,334 @@
+# coding=utf-8
+# --------------------------------------------------------------------
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+# This file is part of code_aster.
+#
+# code_aster is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# code_aster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with code_aster. If not, see .
+# --------------------------------------------------------------------
+
+DEBUT(CODE=_F(NIV_PUB_WEB="INTERNET"))
+
+### >>>>>>>>>>>>>
+### Read the mesh
+### <<<<<<<<<<<<<
+
+MA = LIRE_MAILLAGE(FORMAT="ASTER")
+
+MA = MODI_MAILLAGE(
+ reuse=MA,
+ MAILLAGE=MA,
+ ORIE_PEAU=_F(GROUP_MA_PEAU=("HAUT", "BAS", "DEVANT", "DERRIERE", "DROITE", "GAUCHE")),
+)
+
+### >>>>>>>>>>>>>>>>>
+### Model affectation
+### <<<<<<<<<<<<<<<<<
+
+MO = AFFE_MODELE(MAILLAGE=MA, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="3D_THHM"))
+
+### >>>>>>>>>>>>>>>>>>>
+### Material properties
+### <<<<<<<<<<<<<<<<<<<
+
+# Concrete parameters (BETON_AGEING model)
+
+E = 30.0e9
+NU = 0.2
+KV_VT = 1.0e9
+KD_VT = 1.0e9
+ETAV_VT = 1.0e13
+ETAD_VT = 1.0e13
+KV_MX = 1.0e9
+KD_MX = 1.0e9
+T0 = 0.0
+EA_R = 2100.0
+M_RHOR = 18.0e-3 / (1.0e3 * 8.314)
+TREF = 293.0
+K_FD = 1.0e6
+
+CONCRETE = DEFI_MATERIAU(
+ ELAS=_F(E=E, NU=NU, ALPHA=0.0),
+ BETON_AGEING=_F(
+ YoungModulus=E,
+ PoissonRatio=NU,
+ VoigtSphModulus=KV_VT,
+ VoigtDevModulus=KD_VT,
+ VoigtSphViscosity=ETAV_VT,
+ VoigtDevViscosity=ETAD_VT,
+ MaxwellSphModulus=KV_MX,
+ MaxwellDevModulus=KD_MX,
+ ConcreteInitTime=T0,
+ DessiccationModulus=K_FD,
+ ReferenceTemperature=TREF,
+ ArrheniusIndex=EA_R,
+ KelvinIndex=M_RHOR,
+ ),
+ COMP_THM="LIQU_GAZ",
+ THM_LIQU=_F(
+ RHO=1.0e3,
+ UN_SUR_K=0.0,
+ VISC=DEFI_CONSTANTE(VALE=1.0e-3),
+ D_VISC_TEMP=DEFI_CONSTANTE(VALE=0.0),
+ ALPHA=DEFI_CONSTANTE(VALE=0.0),
+ CP=1.0e3,
+ ),
+ THM_GAZ=_F(
+ MASS_MOL=28.0e-3,
+ VISC=DEFI_CONSTANTE(VALE=1.0e-5),
+ D_VISC_TEMP=DEFI_CONSTANTE(VALE=0.0),
+ CP=1.0e3,
+ ),
+ THM_DIFFU=_F(
+ R_GAZ=8.314,
+ CP=1.0e3,
+ RHO=2.7e3,
+ BIOT_COEF=1.0,
+ PESA_X=0.0,
+ PESA_Y=0.0,
+ PESA_Z=0.0,
+ PERM_IN=DEFI_CONSTANTE(VALE=1.0e-20),
+ VG_N=1.3,
+ VG_PR=1.0e7,
+ VG_SR=0.0,
+ VG_SMAX=0.99,
+ VG_SATUR=1.0,
+ ),
+ THM_INIT=_F(TEMP=TREF, PRE1=0.0, PRE2=1.0e5, PORO=0.2),
+)
+
+### >>>>>>>>>>>>>>>>>>>>
+### Material affectation
+### <<<<<<<<<<<<<<<<<<<<
+
+CHMAT = AFFE_MATERIAU(MAILLAGE=MA, AFFE=_F(TOUT="OUI", MATER=CONCRETE))
+
+### >>>>>>>>>>>>>>>>>>>
+### Boundary conditions
+### <<<<<<<<<<<<<<<<<<<
+
+second = 1.0
+year = 365.0 * (24.0 * 3600.0)
+tload = 28.0 * (24.0 * 3600.0)
+pload = 30.0e6
+
+CL_DEPL = AFFE_CHAR_CINE(
+ MODELE=MO,
+ MECA_IMPO=(
+ _F(GROUP_MA="BAS", DZ=0.0),
+ _F(GROUP_MA="DEVANT", DX=0.0),
+ _F(GROUP_MA="GAUCHE", DY=0.0),
+ ),
+)
+
+CL_PRE1 = AFFE_CHAR_CINE(MODELE=MO, MECA_IMPO=_F(TOUT="OUI", PRE1=0.0))
+
+CL_PRE2 = AFFE_CHAR_CINE(MODELE=MO, MECA_IMPO=_F(TOUT="OUI", PRE2=0.0))
+
+CL_TEMP = AFFE_CHAR_CINE(MODELE=MO, MECA_IMPO=_F(TOUT="OUI", TEMP=0.0))
+
+PRES = DEFI_FONCTION(
+ NOM_PARA="INST",
+ NOM_RESU="PRESSION",
+ VALE=(tload, 0.0, tload + second, pload),
+ PROL_DROITE="CONSTANT",
+)
+
+CL_PRES = AFFE_CHAR_MECA_F(MODELE=MO, PRES_REP=_F(GROUP_MA=("HAUT"), PRES=PRES), VERI_NORM="OUI")
+
+### >>>>>>>>>>
+### Time steps
+### <<<<<<<<<<
+
+TEMPS = DEFI_LIST_REEL(
+ DEBUT=tload, INTERVALLE=(_F(JUSQU_A=tload + second, NOMBRE=10), _F(JUSQU_A=year, NOMBRE=1000))
+)
+
+DEFLIST = DEFI_LIST_INST(
+ DEFI_LIST=_F(LIST_INST=TEMPS),
+ ECHEC=_F(EVENEMENT="ERREUR", ACTION="DECOUPE", SUBD_METHODE="AUTO"),
+)
+### >>>>>>>>
+### Solution
+### <<<<<<<<
+
+RESU = STAT_NON_LINE(
+ MODELE=MO,
+ CHAM_MATER=CHMAT,
+ EXCIT=(
+ _F(CHARGE=CL_DEPL),
+ _F(CHARGE=CL_PRE1),
+ _F(CHARGE=CL_PRE2),
+ _F(CHARGE=CL_TEMP),
+ _F(CHARGE=CL_PRES),
+ ),
+ COMPORTEMENT=_F(RELATION="KIT_THHM", RELATION_KIT=("BETON_AGEING", "LIQU_GAZ", "HYDR_VGM")),
+ INCREMENT=_F(LIST_INST=DEFLIST, INST_INIT=tload, INST_FIN=year),
+ NEWTON=_F(MATRICE="TANGENTE", REAC_ITER=1),
+ CONVERGENCE=_F(ITER_GLOB_MAXI=10, RESI_GLOB_RELA=1.0e-10),
+)
+
+### >>>>>>>>>>>>>>>
+### Post-processing
+### <<<<<<<<<<<<<<<
+
+RESU = CALC_CHAMP(
+ reuse=RESU,
+ RESULTAT=RESU,
+ CONTRAINTE="SIEF_NOEU",
+ DEFORMATION="EPSI_NOEU",
+ VARI_INTERNE="VARI_NOEU",
+)
+
+### >>>>>
+### Tests
+### <<<<<
+
+import numpy as np
+
+### Computation of the reversible part of the creep strain
+def EXX_FP_R(t, ti, sig):
+ return (
+ sig
+ / 3.0
+ * (
+ 1.0 / (3.0 * KV_VT) * (1.0 - np.exp(-KV_VT * (t - ti) / ETAV_VT))
+ - 1.0 / (2.0 * KD_VT) * (1.0 - np.exp(-KD_VT * (t - ti) / ETAD_VT))
+ )
+ )
+
+
+def EZZ_FP_R(t, ti, sig):
+ return (
+ sig
+ / 3.0
+ * (
+ 1.0 / (3.0 * KV_VT) * (1.0 - np.exp(-KV_VT * (t - ti) / ETAV_VT))
+ + 1.0 / KD_VT * (1.0 - np.exp(-KD_VT * (t - ti) / ETAD_VT))
+ )
+ )
+
+
+### Computation of the irreversible part of the creep strain
+def EXX_FP_I(t, t0, ti, sig):
+ return sig / 3.0 * (1.0 / (3.0 * KV_MX) - 1.0 / (2.0 * KD_MX)) * np.log((t - t0) / (ti - t0))
+
+
+def EZZ_FP_I(t, t0, ti, sig):
+ return sig / 3.0 * (1.0 / (3.0 * KV_MX) + 1.0 / KD_MX) * np.log((t - t0) / (ti - t0))
+
+
+### Computation of the total strain
+def EXX(t, t0, ti, sig):
+ EXX_EL = -NU * sig / E
+ return EXX_EL + EXX_FP_R(t, ti, sig) + EXX_FP_I(t, t0, ti, sig)
+
+
+def EZZ(t, t0, ti, sig):
+ EZZ_EL = sig / E
+ return EZZ_EL + EZZ_FP_R(t, ti, sig) + EZZ_FP_I(t, t0, ti, sig)
+
+
+EXX_end = EXX(year, T0, tload + second, -pload)
+EZZ_end = EZZ(year, T0, tload + second, -pload)
+EXX_FP_R_end = EXX_FP_R(year, tload + second, -pload)
+EZZ_FP_R_end = EZZ_FP_R(year, tload + second, -pload)
+EXX_FP_I_end = EXX_FP_I(year, T0, tload + second, -pload)
+EZZ_FP_I_end = EZZ_FP_I(year, T0, tload + second, -pload)
+
+TEST_RESU(
+ RESU=_F(
+ INST=year,
+ RESULTAT=RESU,
+ REFERENCE="ANALYTIQUE",
+ NOM_CHAM="EPSI_NOEU",
+ NOM_CMP="EPXX",
+ GROUP_NO="NO8",
+ PRECISION=0.01,
+ VALE_REFE=EXX_end,
+ VALE_CALC=0.006146144428842571,
+ )
+)
+
+TEST_RESU(
+ RESU=_F(
+ INST=year,
+ RESULTAT=RESU,
+ REFERENCE="ANALYTIQUE",
+ NOM_CHAM="EPSI_NOEU",
+ NOM_CMP="EPZZ",
+ GROUP_NO="NO8",
+ PRECISION=0.01,
+ VALE_REFE=EZZ_end,
+ VALE_CALC=-0.048569155430740474,
+ )
+)
+
+TEST_RESU(
+ RESU=_F(
+ INST=year,
+ RESULTAT=RESU,
+ REFERENCE="ANALYTIQUE",
+ NOM_CHAM="VARI_NOEU",
+ NOM_CMP="V1",
+ GROUP_NO="NO8",
+ PRECISION=0.01,
+ VALE_REFE=EXX_FP_R_end,
+ VALE_CALC=0.0016666666666666722,
+ )
+)
+
+TEST_RESU(
+ RESU=_F(
+ INST=year,
+ RESULTAT=RESU,
+ REFERENCE="ANALYTIQUE",
+ NOM_CHAM="VARI_NOEU",
+ NOM_CMP="V3",
+ GROUP_NO="NO8",
+ PRECISION=0.01,
+ VALE_REFE=EZZ_FP_R_end,
+ VALE_CALC=-0.013333333333333315,
+ )
+)
+
+TEST_RESU(
+ RESU=_F(
+ INST=year,
+ RESULTAT=RESU,
+ REFERENCE="ANALYTIQUE",
+ NOM_CHAM="VARI_NOEU",
+ NOM_CMP="V7",
+ GROUP_NO="NO8",
+ PRECISION=0.01,
+ VALE_REFE=EXX_FP_I_end,
+ VALE_CALC=0.004279477762175899,
+ )
+)
+
+TEST_RESU(
+ RESU=_F(
+ INST=year,
+ RESULTAT=RESU,
+ REFERENCE="ANALYTIQUE",
+ NOM_CHAM="VARI_NOEU",
+ NOM_CMP="V9",
+ GROUP_NO="NO8",
+ PRECISION=0.01,
+ VALE_REFE=EZZ_FP_I_end,
+ VALE_CALC=-0.03423582209740715,
+ )
+)
+
+
+FIN()
diff --git a/astest/wtnv104a.export b/astest/wtnv104a.export
new file mode 100644
index 00000000000..0f07b60e7e9
--- /dev/null
+++ b/astest/wtnv104a.export
@@ -0,0 +1,9 @@
+P time_limit 110
+P memory_limit 512
+P ncpus 1
+P mpi_nbcpu 1
+P mpi_nbnoeud 1
+P testlist verification sequential
+
+F comm wtnv104a.comm D 1
+F mmed wtnv136c.mail D 20
diff --git a/astest/wtnv104b.comm b/astest/wtnv104b.comm
new file mode 100644
index 00000000000..20103b1159a
--- /dev/null
+++ b/astest/wtnv104b.comm
@@ -0,0 +1,230 @@
+# coding=utf-8
+# --------------------------------------------------------------------
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+# This file is part of code_aster.
+#
+# code_aster is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# code_aster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with code_aster. If not, see .
+# --------------------------------------------------------------------
+
+DEBUT(CODE=_F(NIV_PUB_WEB="INTERNET"))
+
+### >>>>>>>>>>>>>
+### Read the mesh
+### <<<<<<<<<<<<<
+
+MA = LIRE_MAILLAGE(FORMAT="ASTER")
+
+MA = MODI_MAILLAGE(
+ reuse=MA,
+ MAILLAGE=MA,
+ ORIE_PEAU=_F(GROUP_MA_PEAU=("HAUT", "BAS", "DEVANT", "DERRIERE", "DROITE", "GAUCHE")),
+)
+
+### >>>>>>>>>>>>>>>>>
+### Model affectation
+### <<<<<<<<<<<<<<<<<
+
+MO = AFFE_MODELE(MAILLAGE=MA, AFFE=_F(TOUT="OUI", PHENOMENE="MECANIQUE", MODELISATION="3D_THHM"))
+
+### >>>>>>>>>>>>>>>>>>>
+### Material properties
+### <<<<<<<<<<<<<<<<<<<
+
+# Concrete parameters (BETON_AGEING model)
+
+E = 30.0e9
+NU = 0.2
+KV_VT = 1.0e9
+KD_VT = 1.0e9
+ETAV_VT = 1.0e13
+ETAD_VT = 1.0e13
+KV_MX = 1.0e9
+KD_MX = 1.0e9
+T0 = 0.0
+EA_R = 2100.0
+M_RHOR = 18.0e-3 / (1.0e3 * 8.314)
+TREF = 293.0
+K_FD = 1.0e9
+
+# Some THM parameters to compute an analytical solution (see the post-process section)
+
+VG_N = 1.3
+VG_PR = 1.0e7
+BIOT = 1.0
+
+CONCRETE = DEFI_MATERIAU(
+ ELAS=_F(E=E, NU=NU, ALPHA=0.0),
+ BETON_AGEING=_F(
+ YoungModulus=E,
+ PoissonRatio=NU,
+ VoigtSphModulus=KV_VT,
+ VoigtDevModulus=KD_VT,
+ VoigtSphViscosity=ETAV_VT,
+ VoigtDevViscosity=ETAD_VT,
+ MaxwellSphModulus=KV_MX,
+ MaxwellDevModulus=KD_MX,
+ ConcreteInitTime=T0,
+ DessiccationModulus=K_FD,
+ ReferenceTemperature=TREF,
+ ArrheniusIndex=EA_R,
+ KelvinIndex=M_RHOR,
+ ),
+ COMP_THM="LIQU_GAZ",
+ THM_LIQU=_F(
+ RHO=1.0e3,
+ UN_SUR_K=0.0,
+ VISC=DEFI_CONSTANTE(VALE=1.0e-3),
+ D_VISC_TEMP=DEFI_CONSTANTE(VALE=0.0),
+ ALPHA=DEFI_CONSTANTE(VALE=0.0),
+ CP=1.0e3,
+ ),
+ THM_GAZ=_F(
+ MASS_MOL=28.0e-3,
+ VISC=DEFI_CONSTANTE(VALE=1.0e-5),
+ D_VISC_TEMP=DEFI_CONSTANTE(VALE=0.0),
+ CP=1.0e3,
+ ),
+ THM_DIFFU=_F(
+ R_GAZ=8.314,
+ CP=1.0e3,
+ RHO=2.7e3,
+ BIOT_COEF=BIOT,
+ PESA_X=0.0,
+ PESA_Y=0.0,
+ PESA_Z=0.0,
+ PERM_IN=DEFI_CONSTANTE(VALE=1.0e-20),
+ VG_N=VG_N,
+ VG_PR=VG_PR,
+ VG_SR=0.0,
+ VG_SMAX=0.99,
+ VG_SATUR=1.0,
+ ),
+ THM_INIT=_F(TEMP=TREF, PRE1=0.0, PRE2=1.0e5, PORO=0.2),
+)
+
+### >>>>>>>>>>>>>>>>>>>>
+### Material affectation
+### <<<<<<<<<<<<<<<<<<<<
+
+CHMAT = AFFE_MATERIAU(MAILLAGE=MA, AFFE=_F(TOUT="OUI", MATER=CONCRETE))
+
+### >>>>>>>>>>>>>>>>>>>
+### Boundary conditions
+### <<<<<<<<<<<<<<<<<<<
+
+tload = 28.0 * (24.0 * 3600.0)
+year = 365.0 * (24.0 * 3600.0)
+pcap_load = 100.0e6
+
+CL_DEPL = AFFE_CHAR_CINE(
+ MODELE=MO,
+ MECA_IMPO=(
+ _F(GROUP_MA="BAS", DZ=0.0),
+ _F(GROUP_MA="DEVANT", DX=0.0),
+ _F(GROUP_MA="GAUCHE", DY=0.0),
+ ),
+)
+
+CL_PRE1 = AFFE_CHAR_CINE(MODELE=MO, MECA_IMPO=_F(TOUT="OUI", PRE1=1.0))
+
+CL_PRE2 = AFFE_CHAR_CINE(MODELE=MO, MECA_IMPO=_F(TOUT="OUI", PRE2=0.0))
+
+CL_TEMP = AFFE_CHAR_CINE(MODELE=MO, MECA_IMPO=_F(TOUT="OUI", TEMP=0.0))
+
+CO_PRE1 = DEFI_FONCTION(NOM_PARA="INST", VALE=(tload, 0.0, year, pcap_load), PROL_DROITE="CONSTANT")
+
+### >>>>>>>>>>
+### Time steps
+### <<<<<<<<<<
+
+TEMPS = DEFI_LIST_REEL(DEBUT=tload, INTERVALLE=(_F(JUSQU_A=year, NOMBRE=1000)))
+
+
+DEFLIST = DEFI_LIST_INST(
+ DEFI_LIST=_F(LIST_INST=TEMPS),
+ ECHEC=_F(EVENEMENT="ERREUR", ACTION="DECOUPE", SUBD_METHODE="AUTO"),
+)
+### >>>>>>>>
+### Solution
+### <<<<<<<<
+
+RESU = STAT_NON_LINE(
+ MODELE=MO,
+ CHAM_MATER=CHMAT,
+ EXCIT=(
+ _F(CHARGE=CL_DEPL),
+ _F(CHARGE=CL_PRE1, FONC_MULT=CO_PRE1),
+ _F(CHARGE=CL_PRE2),
+ _F(CHARGE=CL_TEMP),
+ ),
+ COMPORTEMENT=_F(RELATION="KIT_THHM", RELATION_KIT=("BETON_AGEING", "LIQU_GAZ", "HYDR_VGM")),
+ INCREMENT=_F(LIST_INST=DEFLIST, INST_INIT=tload, INST_FIN=year),
+ NEWTON=_F(MATRICE="TANGENTE", REAC_ITER=1),
+ CONVERGENCE=_F(ITER_GLOB_MAXI=10, RESI_GLOB_RELA=1.0e-8),
+)
+
+### >>>>>>>>>>>>>>>
+### Post-processing
+### <<<<<<<<<<<<<<<
+
+RESU = CALC_CHAMP(
+ reuse=RESU,
+ RESULTAT=RESU,
+ CONTRAINTE="SIEF_NOEU",
+ DEFORMATION="EPSI_NOEU",
+ VARI_INTERNE="VARI_NOEU",
+)
+
+### >>>>>
+### Tests
+### <<<<<
+
+import numpy as np
+from scipy.integrate import quad
+
+
+def sigp(pc):
+ return BIOT * quad(lambda x: (1.0 + (x / VG_PR) ** VG_N) ** (1.0 / VG_N - 1.0), 0, pc)[0]
+
+
+def hr(pc):
+ return np.exp(-M_RHOR * pc / TREF)
+
+
+def dhr(pc):
+ return -M_RHOR / TREF * hr(pc)
+
+
+def eps_dessic(pc):
+ sig = 0.0 # zero total stress applied in the test
+ return quad(lambda x: abs(dhr(x)) * (sig - sigp(x)) / K_FD, 0, pc)[0]
+
+
+EXX_FDESS_end = eps_dessic(pcap_load)
+
+TEST_RESU(
+ RESU=_F(
+ INST=year,
+ RESULTAT=RESU,
+ REFERENCE="ANALYTIQUE",
+ NOM_CHAM="VARI_NOEU",
+ NOM_CMP="V13",
+ GROUP_NO="NO8",
+ PRECISION=0.01,
+ VALE_REFE=EXX_FDESS_end,
+ VALE_CALC=-0.016621556339224738,
+ )
+)
+
+FIN()
diff --git a/astest/wtnv104b.export b/astest/wtnv104b.export
new file mode 100644
index 00000000000..eb7b0fa877a
--- /dev/null
+++ b/astest/wtnv104b.export
@@ -0,0 +1,9 @@
+P time_limit 110
+P memory_limit 512
+P ncpus 1
+P mpi_nbcpu 1
+P mpi_nbnoeud 1
+P testlist verification sequential
+
+F comm wtnv104b.comm D 1
+F mmed wtnv136c.mail D 20
diff --git a/astest/zzzz131a.comm b/astest/zzzz131a.comm
index 7688e2eabb8..6cf7e66bdaa 100644
--- a/astest/zzzz131a.comm
+++ b/astest/zzzz131a.comm
@@ -1,6 +1,6 @@
# coding=utf-8
# --------------------------------------------------------------------
-# Copyright (C) 1991 - 2022 - EDF R&D - www.code-aster.org
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
# This file is part of code_aster.
#
# code_aster is free software: you can redistribute it and/or modify
@@ -606,16 +606,6 @@ RESU11 = EXTR_RESU(RESULTAT=RESU1, ARCHIVAGE=_F(LIST_INST=LINST11))
RESU11 = CALC_CHAMP(reuse=RESU11, DEFORMATION=("DEGE_ELNO"), RESULTAT=RESU11)
-# IMPR_RESU(FORMAT="RESULTAT",RESU=_F(RESULTAT=RESU11))
-
-# POUR COMPLETER LA VALIDATION INFORMATIQUE DE EXTR_RESU : EXTRACTION EN PLACE
-
-RESU12 = EXTR_RESU(RESULTAT=RESU1, ARCHIVAGE=_F(LIST_INST=LINST11))
-RESU12 = EXTR_RESU(reuse=RESU12, RESULTAT=RESU12, ARCHIVAGE=_F(LIST_INST=LINST11))
-
-DETRUIRE(NOM=RESU12)
-
-
DETRUIRE(NOM=RESU1)
CALC_CHAMP(reuse=RESU11, RESULTAT=RESU11, CONTRAINTE="EFGE_NOEU")
diff --git a/astest/zzzz163b.comm b/astest/zzzz163b.comm
index 0b84725b6b4..47d96db7897 100644
--- a/astest/zzzz163b.comm
+++ b/astest/zzzz163b.comm
@@ -159,10 +159,17 @@ ACIER_CS = DEFI_MATERIAU(
CM_CS = AFFE_MATERIAU(MAILLAGE=M, AFFE=_F(TOUT="OUI", MATER=ACIER_CS))
-RESU.setMaterialField(CM_CS)
+RESU_CS = STAT_NON_LINE(
+ MODELE=MO,
+ CHAM_MATER=CM_CS,
+ EXCIT=(_F(CHARGE=CHARG), _F(CHARGE=ZERO)),
+ COMPORTEMENT=_F(RELATION="MFRONT", RESI_INTE=1e-14, COMPOR_MFRONT=BEHAVIOUR),
+ INCREMENT=_F(LIST_INST=L_INST, NUME_INST_FIN=10),
+ CONVERGENCE=_F(RESI_GLOB_RELA=1.0e-10),
+)
PBSMNOMT = POST_BEREMIN(
- RESULTAT=RESU,
+ RESULTAT=RESU_CS,
COEF_MULT=1,
DEFORMATION="PETIT",
GROUP_MA="s_tout",
@@ -172,7 +179,7 @@ PBSMNOMT = POST_BEREMIN(
)
PBSMMT = POST_BEREMIN(
- RESULTAT=RESU,
+ RESULTAT=RESU_CS,
COEF_MULT=1,
DEFORMATION="PETIT",
GROUP_MA="s_tout",
diff --git a/astest/zzzz223a.comm b/astest/zzzz223a.comm
index 7d3755d2074..523ba35af48 100644
--- a/astest/zzzz223a.comm
+++ b/astest/zzzz223a.comm
@@ -217,8 +217,8 @@ IMPR_TABLE(
)
-# validation de la commande EXTR_RESU / ARCHIVAGE (+reuse) :
-# -----------------------------------------------------------
+# validation de la commande EXTR_RESU / ARCHIVAGE
+# -----------------------------------------------
U = CALC_CHAMP(reuse=U, RESULTAT=U, CONTRAINTE=("SIEF_ELGA"))
U2 = EXTR_RESU(RESULTAT=U, ARCHIVAGE=_F(NUME_ORDRE=(3, 5, 7, 9)))
# on appelle 3 fois CALC_CHAMP + MAILLE pour forcer la creation de 3 LIGREL differents
@@ -228,7 +228,6 @@ U2 = CALC_CHAMP(reuse=U2, RESULTAT=U2, CONTRAINTE=("SIGM_ELNO"), NUME_ORDRE=7, G
U2 = CALC_CHAMP(reuse=U2, RESULTAT=U2, CONTRAINTE=("SIGM_ELNO"), NUME_ORDRE=9, GROUP_MA="M1")
U2 = CALC_CHAMP(reuse=U2, RESULTAT=U2, CONTRAINTE="SIGM_NOEU", NUME_ORDRE=(5, 7, 9))
-U3 = EXTR_RESU(RESULTAT=U2, ARCHIVAGE=_F(NUME_ORDRE=(5, 9), CHAM_EXCLU=("SIGM_NOEU")))
-U2 = EXTR_RESU(reuse=U2, RESULTAT=U2, ARCHIVAGE=_F(NUME_ORDRE=(5, 9), CHAM_EXCLU=("SIGM_NOEU")))
+U2 = EXTR_RESU(RESULTAT=U2, ARCHIVAGE=_F(NUME_ORDRE=(5, 9), CHAM_EXCLU=("SIGM_NOEU")))
FIN()
diff --git a/astest/zzzz503d.py b/astest/zzzz503d.py
index 837d1f0ea1f..f3a88355eaa 100644
--- a/astest/zzzz503d.py
+++ b/astest/zzzz503d.py
@@ -78,8 +78,17 @@
affectMat2.addMaterialOnMesh(acier)
affectMat2.build()
-resu.setMaterialField(affectMat2)
-test.assertEqual(affectMat2, resu.getMaterialField())
+with test.assertRaisesRegex(CA.AsterError, "MaterialField already assigned"):
+ resu.setMaterialField(affectMat2)
+
+# unchanged
+test.assertEqual(affectMat, resu.getMaterialField())
+
+# does nothing, silently
+resu.setMaterialField(affectMat2, exists_ok=True)
+
+# unchanged
+test.assertEqual(affectMat, resu.getMaterialField())
test.printSummary()
diff --git a/bibc/include/aster_fort_mesh.h b/bibc/include/aster_fort_mesh.h
index da4d8fb1ae0..83290154504 100644
--- a/bibc/include/aster_fort_mesh.h
+++ b/bibc/include/aster_fort_mesh.h
@@ -1,5 +1,5 @@
/* -------------------------------------------------------------------- */
-/* Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org */
+/* Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org */
/* This file is part of code_aster. */
/* */
/* code_aster is free software: you can redistribute it and/or modify */
@@ -117,6 +117,31 @@ extern void DEFSSPSSSSPS( AJELLT, ajellt, const char *, STRING_SIZE, const char
STRING_SIZE, const char *, STRING_SIZE, const char *, STRING_SIZE,
const ASTERINTEGER *, const char *, STRING_SIZE );
+#define CALLO_PAIRWRAP( a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q ) \
+ CALLPOOOOOPPPPPPPPPPO( PAIRWRAP, pairwrap, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q )
+extern void DEFPSSSSSPPPPPPPPPPS( PAIRWRAP, pairwrap, ASTERINTEGER *, const char *, STRING_SIZE,
+ const char *, STRING_SIZE, const char *, STRING_SIZE,
+ const char *, STRING_SIZE, const char *, STRING_SIZE,
+ ASTERDOUBLE *, ASTERDOUBLE *, ASTERINTEGER *, ASTERINTEGER *,
+ ASTERINTEGER *, ASTERINTEGER *, ASTERINTEGER *, ASTERINTEGER *,
+ ASTERINTEGER *, ASTERINTEGER *, const char *, STRING_SIZE );
+
+#define CALLO_INTECELLAREAWRAP( a, b, c, d ) \
+ CALLOPPP( INTECELLAREAWRAP, intecellareawrap, a, b, c, d )
+extern void DEFSPPP( INTECELLAREAWRAP, intecellareawrap, const char *, STRING_SIZE, ASTERINTEGER *,
+ ASTERDOUBLE *, ASTERDOUBLE * );
+
+#define CALLO_INTEPOINCOORWRAP( a, b, c, d, e ) \
+ CALLOOOPP( INTEPOINCOORWRAP, intepoincoorwrap, a, b, c, d, e )
+extern void DEFSSSPP( INTEPOINCOORWRAP, intepoincoorwrap, const char *, STRING_SIZE, const char *,
+ STRING_SIZE, const char *, STRING_SIZE, const ASTERINTEGER *, ASTERDOUBLE * );
+
+#define CALLO_QUADPOINCOORWRAP( a, b, c, d, e, f ) \
+ CALLOOOPPP( QUADPOINCOORWRAP, quadpoincoorwrap, a, b, c, d, e, f )
+extern void DEFSSSPPP( QUADPOINCOORWRAP, quadpoincoorwrap, const char *, STRING_SIZE, const char *,
+ STRING_SIZE, const char *, STRING_SIZE, const ASTERINTEGER *, ASTERINTEGER *,
+ ASTERDOUBLE * );
+
#ifdef __cplusplus
}
#endif
diff --git a/bibc/include/definition.h b/bibc/include/definition.h
index 07cbe0bbccf..6520d96419a 100644
--- a/bibc/include/definition.h
+++ b/bibc/include/definition.h
@@ -171,6 +171,9 @@
#define DEFSSPPS(UN,LN,a,la,b,lb,c,d,e,le) STDCALL(UN,LN)(a,b,c,d,e,la,lb,le)
#define CALLSSPPS(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)(a,b,c,d,e,strlen(a),strlen(b),strlen(e))
#define CALLOOPPO(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)((a).c_str(),(b).c_str(),c,d,(e).c_str(),(a).size(),(b).size(),(e).size())
+#define DEFSSSPP(UN,LN,a,la,b,lb,c,lc,d,e) STDCALL(UN,LN)(a,b,c,d,e,la,lb,lc)
+#define CALLSSSPP(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)(a,b,c,d,e,strlen(a),strlen(b),strlen(c))
+#define CALLOOOPP(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)((a).c_str(),(b).c_str(),(c).c_str(),d,e,(a).size(),(b).size(),(c).size())
#define DEFSSSSP(UN,LN,a,la,b,lb,c,lc,d,ld,e) STDCALL(UN,LN)(a,b,c,d,e,la,lb,lc,ld)
#define CALLSSSSP(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)(a,b,c,d,e,strlen(a),strlen(b),strlen(c),strlen(d))
#define CALLOOOOP(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)((a).c_str(),(b).c_str(),(c).c_str(),(d).c_str(),e,(a).size(),(b).size(),(c).size(),(d).size())
@@ -198,6 +201,9 @@
#define DEFSSPSSP(UN,LN,a,la,b,lb,c,d,ld,e,le,f) STDCALL(UN,LN)(a,b,c,d,e,f,la,lb,ld,le)
#define CALLSSPSSP(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)(a,b,c,d,e,f,strlen(a),strlen(b),strlen(d),strlen(e))
#define CALLOOPOOP(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)((a).c_str(),(b).c_str(),c,(d).c_str(),(e).c_str(),f,(a).size(),(b).size(),(d).size(),(e).size())
+#define DEFSSSPPP(UN,LN,a,la,b,lb,c,lc,d,e,f) STDCALL(UN,LN)(a,b,c,d,e,f,la,lb,lc)
+#define CALLSSSPPP(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)(a,b,c,d,e,f,strlen(a),strlen(b),strlen(c))
+#define CALLOOOPPP(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)((a).c_str(),(b).c_str(),(c).c_str(),d,e,f,(a).size(),(b).size(),(c).size())
#define DEFSSSPSS(UN,LN,a,la,b,lb,c,lc,d,e,le,f,lf) STDCALL(UN,LN)(a,b,c,d,e,f,la,lb,lc,le,lf)
#define CALLSSSPSS(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)(a,b,c,d,e,f,strlen(a),strlen(b),strlen(c),strlen(e),strlen(f))
#define CALLOOOPOO(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)((a).c_str(),(b).c_str(),(c).c_str(),d,(e).c_str(),(f).c_str(),(a).size(),(b).size(),(c).size(),(e).size(),(f).size())
@@ -333,6 +339,9 @@
#define DEFSSSSPPPPPPPPPSSS(UN,LN,a,la,b,lb,c,lc,d,ld,e,f,g,h,i,j,k,l,m,n,ln,o,lo,p,lp) STDCALL(UN,LN)(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,la,lb,lc,ld,ln,lo,lp)
#define CALLSSSSPPPPPPPPPSSS(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) F_FUNC(UN,LN)(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,strlen(a),strlen(b),strlen(c),strlen(d),strlen(n),strlen(o),strlen(p))
#define CALLOOOOPPPPPPPPPOOO(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) F_FUNC(UN,LN)((a).c_str(),(b).c_str(),(c).c_str(),(d).c_str(),e,f,g,h,i,j,k,l,m,(n).c_str(),(o).c_str(),(p).c_str(),(a).size(),(b).size(),(c).size(),(d).size(),(n).size(),(o).size(),(p).size())
+#define DEFPSSSSSPPPPPPPPPPS(UN,LN,a,b,lb,c,lc,d,ld,e,le,f,lf,g,h,i,j,k,l,m,n,o,p,q,lq) STDCALL(UN,LN)(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,lb,lc,ld,le,lf,lq)
+#define CALLPSSSSSPPPPPPPPPPS(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) F_FUNC(UN,LN)(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,strlen(b),strlen(c),strlen(d),strlen(e),strlen(f),strlen(q))
+#define CALLPOOOOOPPPPPPPPPPO(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) F_FUNC(UN,LN)(a,(b).c_str(),(c).c_str(),(d).c_str(),(e).c_str(),(f).c_str(),g,h,i,j,k,l,m,n,o,p,(q).c_str(),(b).size(),(c).size(),(d).size(),(e).size(),(f).size(),(q).size())
#define DEFPPPPPPPPPPPPPPPPPPPSPPPPPPPPPPPPPPPPPP(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,lt,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L) STDCALL(UN,LN)(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,lt)
#define CALLPPPPPPPPPPPPPPPPPPPSPPPPPPPPPPPPPPPPPP(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L) F_FUNC(UN,LN)(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,strlen(t))
#define CALLPPPPPPPPPPPPPPPPPPPOPPPPPPPPPPPPPPPPPP(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L) F_FUNC(UN,LN)(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,(t).c_str(),u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,(t).size())
@@ -433,6 +442,9 @@
#define DEFSSPPS(UN,LN,a,la,b,lb,c,d,e,le) STDCALL(UN,LN)(a,la,b,lb,c,d,e,le)
#define CALLSSPPS(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)(a,strlen(a),b,strlen(b),c,d,e,strlen(e))
#define CALLOOPPO(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)((a).c_str(),(a).size(),(b).c_str(),(b).size(),c,d,(e).c_str(),(e).size())
+#define DEFSSSPP(UN,LN,a,la,b,lb,c,lc,d,e) STDCALL(UN,LN)(a,la,b,lb,c,lc,d,e)
+#define CALLSSSPP(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)(a,strlen(a),b,strlen(b),c,strlen(c),d,e)
+#define CALLOOOPP(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)((a).c_str(),(a).size(),(b).c_str(),(b).size(),(c).c_str(),(c).size(),d,e)
#define DEFSSSSP(UN,LN,a,la,b,lb,c,lc,d,ld,e) STDCALL(UN,LN)(a,la,b,lb,c,lc,d,ld,e)
#define CALLSSSSP(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)(a,strlen(a),b,strlen(b),c,strlen(c),d,strlen(d),e)
#define CALLOOOOP(UN,LN,a,b,c,d,e) F_FUNC(UN,LN)((a).c_str(),(a).size(),(b).c_str(),(b).size(),(c).c_str(),(c).size(),(d).c_str(),(d).size(),e)
@@ -460,6 +472,9 @@
#define DEFSSPSSP(UN,LN,a,la,b,lb,c,d,ld,e,le,f) STDCALL(UN,LN)(a,la,b,lb,c,d,ld,e,le,f)
#define CALLSSPSSP(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)(a,strlen(a),b,strlen(b),c,d,strlen(d),e,strlen(e),f)
#define CALLOOPOOP(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)((a).c_str(),(a).size(),(b).c_str(),(b).size(),c,(d).c_str(),(d).size(),(e).c_str(),(e).size(),f)
+#define DEFSSSPPP(UN,LN,a,la,b,lb,c,lc,d,e,f) STDCALL(UN,LN)(a,la,b,lb,c,lc,d,e,f)
+#define CALLSSSPPP(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)(a,strlen(a),b,strlen(b),c,strlen(c),d,e,f)
+#define CALLOOOPPP(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)((a).c_str(),(a).size(),(b).c_str(),(b).size(),(c).c_str(),(c).size(),d,e,f)
#define DEFSSSPSS(UN,LN,a,la,b,lb,c,lc,d,e,le,f,lf) STDCALL(UN,LN)(a,la,b,lb,c,lc,d,e,le,f,lf)
#define CALLSSSPSS(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)(a,strlen(a),b,strlen(b),c,strlen(c),d,e,strlen(e),f,strlen(f))
#define CALLOOOPOO(UN,LN,a,b,c,d,e,f) F_FUNC(UN,LN)((a).c_str(),(a).size(),(b).c_str(),(b).size(),(c).c_str(),(c).size(),d,(e).c_str(),(e).size(),(f).c_str(),(f).size())
@@ -595,6 +610,9 @@
#define DEFSSSSPPPPPPPPPSSS(UN,LN,a,la,b,lb,c,lc,d,ld,e,f,g,h,i,j,k,l,m,n,ln,o,lo,p,lp) STDCALL(UN,LN)(a,la,b,lb,c,lc,d,ld,e,f,g,h,i,j,k,l,m,n,ln,o,lo,p,lp)
#define CALLSSSSPPPPPPPPPSSS(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) F_FUNC(UN,LN)(a,strlen(a),b,strlen(b),c,strlen(c),d,strlen(d),e,f,g,h,i,j,k,l,m,n,strlen(n),o,strlen(o),p,strlen(p))
#define CALLOOOOPPPPPPPPPOOO(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) F_FUNC(UN,LN)((a).c_str(),(a).size(),(b).c_str(),(b).size(),(c).c_str(),(c).size(),(d).c_str(),(d).size(),e,f,g,h,i,j,k,l,m,(n).c_str(),(n).size(),(o).c_str(),(o).size(),(p).c_str(),(p).size())
+#define DEFPSSSSSPPPPPPPPPPS(UN,LN,a,b,lb,c,lc,d,ld,e,le,f,lf,g,h,i,j,k,l,m,n,o,p,q,lq) STDCALL(UN,LN)(a,b,lb,c,lc,d,ld,e,le,f,lf,g,h,i,j,k,l,m,n,o,p,q,lq)
+#define CALLPSSSSSPPPPPPPPPPS(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) F_FUNC(UN,LN)(a,b,strlen(b),c,strlen(c),d,strlen(d),e,strlen(e),f,strlen(f),g,h,i,j,k,l,m,n,o,p,q,strlen(q))
+#define CALLPOOOOOPPPPPPPPPPO(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) F_FUNC(UN,LN)(a,(b).c_str(),(b).size(),(c).c_str(),(c).size(),(d).c_str(),(d).size(),(e).c_str(),(e).size(),(f).c_str(),(f).size(),g,h,i,j,k,l,m,n,o,p,(q).c_str(),(q).size())
#define DEFPPPPPPPPPPPPPPPPPPPSPPPPPPPPPPPPPPPPPP(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,lt,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L) STDCALL(UN,LN)(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,lt,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L)
#define CALLPPPPPPPPPPPPPPPPPPPSPPPPPPPPPPPPPPPPPP(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L) F_FUNC(UN,LN)(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,strlen(t),u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L)
#define CALLPPPPPPPPPPPPPPPPPPPOPPPPPPPPPPPPPPPPPP(UN,LN,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L) F_FUNC(UN,LN)(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,(t).c_str(),(t).size(),u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L)
diff --git a/bibcxx/Contact/ContactComputation.cxx b/bibcxx/Contact/ContactComputation.cxx
index e6327b3ce5f..91a3ab2bd1d 100644
--- a/bibcxx/Contact/ContactComputation.cxx
+++ b/bibcxx/Contact/ContactComputation.cxx
@@ -29,36 +29,34 @@
#include "Numbering/DOFNumbering.h"
#include "Utilities/Tools.h"
-/**
- * @brief Compute contact mortar matrix
- */
-FieldOnCellsRealPtr ContactComputation::contactData( const ContactPairingPtr pairing,
+FieldOnCellsRealPtr ContactComputation::contactData( const ContactPairingPtr contPairing,
const MaterialFieldPtr mater,
const bool &initial_contact ) const {
CALL_JEMARQ();
- auto fed = pairing->getFiniteElementDescriptor();
+ // Get finite element descriptor
+ auto fed = contPairing->getFiniteElementDescriptor();
// Field for intersection points and other thing ...
auto data = FieldOnCellsPtrBuilder< ASTERDOUBLE >( fed, "CHAR_MECA_CONT", "PCONFR" );
- ASTERINTEGER nbContPair = pairing->getNumberOfPairs();
- auto nbInter = concatenate( pairing->getNumberOfIntersectionPoints() );
- auto inter = concatenate( pairing->getSlaveIntersectionPoints() );
- auto listPairs = pairing->getListOfPairs();
- AS_ASSERT( nbContPair == nbInter.size() );
- AS_ASSERT( 16 * nbContPair == inter.size() );
+ // Get pairing
+ ASTERINTEGER nbContPair = contPairing->getNumberOfPairs();
+ VectorLong nbInter = contPairing->getNumberOfIntersectionPoints();
+ std::vector< VectorOfVectorsReal > inter =
+ contPairing->getIntersectionPoints( CoordinatesSpace::Slave );
+ VectorPairLong listPairs = contPairing->getListOfPairs();
+ MapLong globPairToLocaPair = contPairing->globPairToLocaPair();
- auto pair2Zone = pairing->pairsToZones();
+ AS_ASSERT( nbContPair == nbInter.size() );
+ // Acces to list of cells
+ const JeveuxCollectionLong meshConnex = contPairing->getMesh()->getConnectivity();
+ MapLong pair2Zone = contPairing->pairsToZones();
auto grel = fed->getListOfGroupsOfElements();
auto nbGrel = data->getNumberOfGroupOfElements();
- auto meshConnectivty = pairing->getMesh()->getConnectivity();
-
- ASTERINTEGER nbPair = 0;
-
- // create local mapping
+ // Create local mapping (for Nitsche)
auto mapping = []( const VectorLong &surf_nodes, const VectorLong &volu_nodes ) {
VectorLong mapping;
mapping.reserve( surf_nodes.size() );
@@ -77,34 +75,44 @@ FieldOnCellsRealPtr ContactComputation::contactData( const ContactPairingPtr pai
return mapping;
};
- // get Material
+ // Get material (for Nitsche)
auto listMaterial = mater->getVectorOfMaterial();
- // Loop on Grel
+ // Loop on groups of elements
+ ASTERINTEGER nbPair = 0;
for ( ASTERINTEGER iGrel = 0; iGrel < nbGrel; iGrel++ ) {
auto nbElem = data->getNumberOfElements( iGrel );
- // size from catalogue
AS_ASSERT( data->getSizeOfFieldOfElement( iGrel ) == 60 );
auto liel = ( *grel )[iGrel + 1];
liel->updateValuePointer();
+ // Loop on elements
for ( ASTERINTEGER iElem = 0; iElem < nbElem; iElem++ ) {
+ // Get mesh cell index
auto iPair = -( *liel )[iElem];
if ( iPair <= nbContPair ) {
+ // Current contact zone
auto iZone = pair2Zone[iPair - 1];
auto zone = _contact->getContactZone( iZone );
+
// Adress in field
auto shift = data->getShifting( iGrel, iElem );
- // Number of intersection points
+ // Set number of intersection points
( *data )[shift + 0] = nbInter[iPair - 1];
- // Parametric coordinates
- for ( ASTERINTEGER i = 0; i < 16; i++ ) {
- ( *data )[shift + 1 + i] = inter[16 * ( iPair - 1 ) + i];
+ AS_ASSERT( nbInter[iPair - 1] <= 8 );
+
+ // Set coordinates of slave intersection points
+ for ( ASTERINTEGER iInter = 0; iInter < 8; iInter++ ) {
+ if ( iInter < nbInter[iPair - 1] ) {
+ auto iLocaPair = iPair - 1 - globPairToLocaPair[iZone];
+ ( *data )[shift + 1 + iInter] = inter[iZone][iLocaPair][2 * iInter];
+ ( *data )[shift + 9 + iInter] = inter[iZone][iLocaPair][2 * iInter + 1];
+ }
}
-
- /// Contact parameter
+ // Contact parameter
auto cont = zone->getContactParameter();
+
// Value for ALGO_CONT
( *data )[shift + 23] = double( cont->getAlgorithm() );
// Value for TYPE_CONT
@@ -131,8 +139,10 @@ FieldOnCellsRealPtr ContactComputation::contactData( const ContactPairingPtr pai
/// Other
auto pair = zone->getPairingParameter();
+
// Value for projection tolerancetolerance
( *data )[shift + 40] = 1.e-8;
+
// Status to impose to contact
if ( initial_contact ) {
( *data )[shift + 41] = double( pair->getInitialState() );
@@ -140,15 +150,17 @@ FieldOnCellsRealPtr ContactComputation::contactData( const ContactPairingPtr pai
( *data )[shift + 41] = double( InitialState::Interpenetrated );
}
- /// Nitsche
+ // Nitsche
if ( cont->getAlgorithm() == ContactAlgo::Nitsche ) {
auto [slavCellNume, mastCellNume] = listPairs[iPair - 1];
- auto slav_surf_con = ( *meshConnectivty )[slavCellNume + 1]->toVector();
+ auto slav_surf_con = ( *meshConnex )[slavCellNume + 1]->toVector();
auto slavVoluNume = zone->getSlaveCellSurfToVolu( slavCellNume );
- auto slav_volu_con = ( *meshConnectivty )[slavVoluNume + 1]->toVector();
+ auto slav_volu_con = ( *meshConnex )[slavVoluNume + 1]->toVector();
+
auto mapLoc = mapping( slav_surf_con, slav_volu_con );
// Number of nodes
( *data )[shift + 50] = double( mapLoc.size() );
+
// Mapping
auto i = 0;
for ( auto &nodeId : mapLoc ) {
@@ -159,7 +171,7 @@ FieldOnCellsRealPtr ContactComputation::contactData( const ContactPairingPtr pai
AS_ASSERT( listMaterial.size() == 1 );
// Young modulus
( *data )[shift + 45] = listMaterial[0]->getValueReal( "ELAS", "E" );
- // Poisson ration
+ // Poisson ratio
( *data )[shift + 46] = listMaterial[0]->getValueReal( "ELAS", "NU" );
}
@@ -174,22 +186,19 @@ FieldOnCellsRealPtr ContactComputation::contactData( const ContactPairingPtr pai
return data;
};
-/**
- * @brief Compute contact mortar matrix
- */
std::pair< FieldOnNodesRealPtr, FieldOnNodesRealPtr >
ContactComputation::contactCoefficient() const {
// Create FieldOnNodes
- auto ccont =
+ auto fieldCont =
std::make_shared< FieldOnNodesReal >( _contact->getFiniteElementDescriptor(), "ECCONT" );
- ccont->updateValuePointers();
+ fieldCont->updateValuePointers();
- auto cfrot =
+ auto fieldFric =
std::make_shared< FieldOnNodesReal >( _contact->getFiniteElementDescriptor(), "ECFROT" );
- cfrot->updateValuePointers();
+ fieldFric->updateValuePointers();
- auto dof2nodes = ccont->getDescription()->getNodeAndComponentIdFromDOF();
+ auto dof2nodes = fieldCont->getDescription()->getNodeAndComponentIdFromDOF();
MapLong nodes2dof;
for ( ASTERINTEGER i_eq = 0; i_eq < dof2nodes.size(); i_eq++ ) {
auto [node, cmp] = dof2nodes[i_eq];
@@ -201,14 +210,13 @@ ContactComputation::contactCoefficient() const {
for ( auto &zone : zones ) {
auto coef_cont = zone->getContactParameter()->getCoefficient();
-
auto coef_frot = zone->getFrictionParameter()->getCoefficient();
auto nodes = zone->getSlaveNodes();
for ( auto &node : nodes ) {
- ( *ccont )[nodes2dof[node]] = coef_cont;
- ( *cfrot )[nodes2dof[node]] = coef_frot;
+ ( *fieldCont )[nodes2dof[node]] = coef_cont;
+ ( *fieldFric )[nodes2dof[node]] = coef_frot;
}
}
- return std::make_pair( ccont, cfrot );
+ return std::make_pair( fieldCont, fieldFric );
};
diff --git a/bibcxx/Contact/ContactComputation.h b/bibcxx/Contact/ContactComputation.h
index 442b1300a22..3b0168a910f 100644
--- a/bibcxx/Contact/ContactComputation.h
+++ b/bibcxx/Contact/ContactComputation.h
@@ -33,35 +33,39 @@ class ContactComputation {
// Contact Definition
ContactNewPtr _contact;
- /**
- * @brief Convert ELNO -> NOEU for virtual nodes
- */
+ /** @brief Convert ELNO -> NOEU for virtual nodes */
FieldOnNodesRealPtr convertVirtualField( const FieldOnCellsRealPtr field ) const;
+ /** @brief Level of verbosity */
+ ASTERINTEGER _verbosity;
+
public:
+ /** @brief Main constructor */
ContactComputation( const ContactNewPtr contact ) : _contact( contact ) {};
- /** @brief restricted constructor (Set) and method (Get) to support pickling */
+ /** @brief Restricted constructor (Set) to support pickling */
ContactComputation( const py::tuple &tup )
: ContactComputation( tup[0].cast< ContactNewPtr >() ) {};
+
+ /** @brief Method (Get) to support pickling */
py::tuple _getState() const { return py::make_tuple( _contact ); };
- /**
- * @brief Compute contact mortar matrix
- */
+ /** @brief Compute contact mortar matrix */
ElementaryMatrixDisplacementRealPtr contactMortarMatrix() const;
- FieldOnCellsRealPtr contactData( const ContactPairingPtr pairing, const MaterialFieldPtr mater,
+ /** @brief Compute field for input data in elementary computations of contact */
+ FieldOnCellsRealPtr contactData( const ContactPairingPtr contPairing,
+ const MaterialFieldPtr mater,
const bool &initial_contact ) const;
- /**
- * @brief Compute contact coefficient field (COEF_CONT)
- */
+ /** @brief Compute contact coefficient field (COEF_CONT) */
std::pair< FieldOnNodesRealPtr, FieldOnNodesRealPtr > contactCoefficient() const;
+
+ /** @brief Set verbosity */
+ void setVerbosity( const ASTERINTEGER &level ) { _verbosity = level; }
+
+ /** @brief Get verbosity */
+ ASTERINTEGER getVerbosity() const { return _verbosity; }
};
-/**
- * @typedef ContactComputationPtr
- * @brief Pointeur intelligent vers un ContactComputation
- */
-typedef std::shared_ptr< ContactComputation > ContactComputationPtr;
+using ContactComputationPtr = std::shared_ptr< ContactComputation >;
diff --git a/bibcxx/Contact/ContactNew.cxx b/bibcxx/Contact/ContactNew.cxx
index ddb0bcd744e..36e19868094 100644
--- a/bibcxx/Contact/ContactNew.cxx
+++ b/bibcxx/Contact/ContactNew.cxx
@@ -44,30 +44,41 @@ ContactNew::ContactNew( const std::string name, const ModelPtr model, const std:
UTMESS( "F", "CONTACT1_2" );
};
-bool ContactNew::build() {
- CALL_JEMARQ();
+void ContactNew::appendContactZone( const ContactZonePtr zone ) {
+ _zones.push_back( zone );
+ _zones.back()->setVerbosity( getVerbosity() );
+}
- auto mesh = getMesh();
+ASTERINTEGER ContactNew::getSpaceDime() const {
- // calico
- ASTERINTEGER nb_dim = 0;
- ASTERINTEGER nb_dim_ = getModel()->getGeometricDimension();
- if ( nb_dim_ > 3 ) { // general ? dans model ?
+ ASTERINTEGER spaceDime = 0;
+ ASTERINTEGER spaceDime_ = getModel()->getGeometricDimension();
+ if ( spaceDime_ > 3 ) {
UTMESS( "A", "CONTACT_84" );
- if ( nb_dim_ == 1003 ) {
- nb_dim = 3;
- } else if ( nb_dim_ == 1002 ) {
- nb_dim = 2;
- } else if ( nb_dim_ == 23 ) {
- nb_dim = 2;
+ if ( spaceDime_ == 1003 ) {
+ spaceDime = 3;
+ } else if ( spaceDime_ == 1002 ) {
+ spaceDime = 2;
+ } else if ( spaceDime_ == 23 ) {
+ spaceDime = 2;
} else {
UTMESS( "F", "CONTACT1_4" );
}
} else {
- nb_dim = nb_dim_;
+ spaceDime = spaceDime_;
}
+ return spaceDime;
+}
- // define name of catalogue
+bool ContactNew::build() {
+ CALL_JEMARQ();
+
+ auto mesh = getMesh();
+
+ // Space dimension
+ ASTERINTEGER spaceDime = this->getSpaceDime();
+
+ // Define name of catalogue
std::map< std::tuple< ASTERINTEGER, ContactAlgo, bool >, std::string > cata;
cata[std::make_tuple( 2, ContactAlgo::Lagrangian, false )] = "CONT_LAG_SL_2D";
@@ -88,8 +99,10 @@ bool ContactNew::build() {
ASTERINTEGER nb_slave_cells = 0;
- // sdcont_defi.CONTACT.MAILCO/NOEUCO/ssnoco
+ // List of all contact cells
std::vector< std::pair< VectorLong, std::string > > mailco;
+
+ // List of all contact nodes
std::vector< VectorLong > noeuco;
for ( auto &zone_i : _zones ) {
@@ -101,12 +114,12 @@ bool ContactNew::build() {
nb_slave_cells += l_slave_cells.size();
mailco.push_back( std::make_pair(
l_slave_cells,
- cata[std::make_tuple( nb_dim, zone_i->getContactParameter()->getAlgorithm(),
+ cata[std::make_tuple( spaceDime, zone_i->getContactParameter()->getAlgorithm(),
zone_i->hasFriction() )] ) );
noeuco.push_back( l_slave_nodes );
}
- // check the common slave nodes between zones (or cells ?)
+ // Check the common slave nodes between zones (or cells ?)
VectorLong doublNodes;
for ( auto it = noeuco.begin(); it != noeuco.end(); ++it ) {
VectorLong l_a = *it;
@@ -130,12 +143,12 @@ bool ContactNew::build() {
}
#endif
if ( nb_doublNodes > 0 ) {
- UTMESS( "F", "CONTACT1_3" );
+ UTMESS( "F", "CONTACT1_1" );
}
}
}
- // create slave elements in model : routine mmprel
+ // Sreate slave elements in model : routine mmprel
std::string ligret = ljust( "&&OP0030.LIGRET", 19, ' ' );
std::string phenom = ljust( "MECANIQUE", 16, ' ' );
std::string modeli;
@@ -211,7 +224,6 @@ VectorLong ContactNew::getSlaveCells() const {
cells.insert( l_slave_cells.begin(), l_slave_cells.end() );
}
-
return VectorLong( cells.begin(), cells.end() );
};
@@ -227,7 +239,6 @@ bool ContactNew::hasFriction() const {
return true;
}
}
-
return false;
};
@@ -243,6 +254,24 @@ bool ContactNew::hasSmoothing() const {
return true;
}
}
-
return false;
};
+
+void ContactNew::setVerbosity( const ASTERINTEGER &level ) {
+ _verbosity = level;
+ for ( auto &zone : _zones ) {
+ zone->setVerbosity( level );
+ }
+}
+
+VectorLong ContactNew::getNumberOfIntersectionPoints() const {
+ VectorLong returnValue;
+
+ return returnValue;
+}
+
+VectorLong ContactNew::getNumberOfIntersectionPoints( const ASTERINTEGER &indexZone ) const {
+ VectorLong returnValue;
+
+ return returnValue;
+}
diff --git a/bibcxx/Contact/ContactNew.h b/bibcxx/Contact/ContactNew.h
index 60db251dcb8..c887911fb98 100644
--- a/bibcxx/Contact/ContactNew.h
+++ b/bibcxx/Contact/ContactNew.h
@@ -1,8 +1,8 @@
/**
* @file ContactNew.h
- * @brief Fichier entete de la class ContactNew
+ * @brief Header of class ContactNew
* @section LICENCE
- * Copyright (C) 1991 - 2023 EDF R&D www.code-aster.org
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
*
* This file is part of Code_Aster.
*
@@ -33,126 +33,142 @@
class ContactNew : public DataStructure {
protected:
- /** @brief Modele */
+ /** @brief Model */
ModelPtr _model;
- /** @brief Ligel ".CHME.LIGRE" */
+
+ /** @brief Ligrel ".CHME.LIGRE" */
FiniteElementDescriptorPtr _FEDesc;
- /** @brief List of contact zone */
+
+ /** @brief List of contact zones */
std::vector< ContactZonePtr > _zones;
+
/** @brief Level of verbosity */
ASTERINTEGER _verbosity;
- /**
- * @brief Constructeur
- */
+ protected:
+ /** @brief Main constructor */
ContactNew( const std::string name, const ModelPtr model, const std::string type );
- public:
- typedef std::vector< std::pair< ASTERINTEGER, ASTERINTEGER > > VectorLongPairs;
+ private:
+ /** @brief Get global dimension of space */
+ ASTERINTEGER getSpaceDime() const;
- /**
- * @typedef ContactNewPtr
- * @brief Pointeur intelligent vers un ContactNew
- */
- typedef std::shared_ptr< ContactNew > ContactNewPtr;
+ public:
+ using ContactNewPtr = std::shared_ptr< ContactNew >;
- /**
- * @brief Constructeur
- */
+ /** @brief No default constructor */
ContactNew() = delete;
- /**
- * @brief Constructeur
- */
+ /** @brief Constructor with given name */
ContactNew( const std::string name, const ModelPtr model )
: ContactNew( name, model, "CHAR_CONT" ) {};
- /**
- * @brief Constructeur
- */
+ /** @brief Constructor with automatic name */
ContactNew( const ModelPtr model ) : ContactNew( ResultNaming::getNewResultName(), model ) {};
- /**
- * @brief Get Model
- */
+ /** @brief Get mesh */
+ BaseMeshPtr getMesh() const { return _model->getMesh(); }
+
+ /** @brief Get model */
ModelPtr getModel() const { return _model; }
- /**
- * @brief Get FiniteElementDescriptor
- */
+ /** @brief Get Finite Element Descriptor */
FiniteElementDescriptorPtr getFiniteElementDescriptor() const { return _FEDesc; }
- BaseMeshPtr getMesh() const { return _model->getMesh(); }
+ /** @brief Set verbosity */
+ void setVerbosity( const ASTERINTEGER &level );
- void appendContactZone( const ContactZonePtr zone ) { _zones.push_back( zone ); }
+ /** @brief Get verbosity */
+ ASTERINTEGER getVerbosity() const { return _verbosity; }
+
+ /** @brief Append contact zone */
+ void appendContactZone( const ContactZonePtr zone );
+ /** @brief Get number of contact zones */
ASTERINTEGER getNumberOfContactZones() const { return _zones.size(); }
+ /** @brief Get contact zone */
ContactZonePtr getContactZone( const ASTERINTEGER &zone_id ) const {
return _zones.at( zone_id );
}
- std::vector< ContactZonePtr > getContactZones() const { return _zones; }
+ /** @brief Get pair geometry of zone */
+ MeshPairingPtr getMeshPairing( const ASTERINTEGER &zone_id ) {
+ return _zones.at( zone_id )->getMeshPairing();
+ };
- void setVerbosity( const ASTERINTEGER &level ) { _verbosity = level; }
+ /** @brief Clear pairing result of zone */
+ void clearPairing( const ASTERINTEGER &zone_id ) {
+ _zones.at( zone_id )->getMeshPairing()->clearResult();
+ };
- ASTERINTEGER getVerbosity() const { return _verbosity; }
+ /** @brief Update coordinates */
+ void updateCoordinates( const FieldOnNodesRealPtr &disp ) {
+ for ( auto &zone : _zones ) {
+ zone->updateCoordinates( disp );
+ }
+ };
- bool build();
+ /** @brief Set coordinates */
+ void setCoordinates( const MeshCoordinatesFieldPtr &coor ) {
+ for ( auto &zone : _zones ) {
+ zone->setCoordinates( coor );
+ }
+ };
+
+ /** @brief Get all contact zones */
+ std::vector< ContactZonePtr > getContactZones() const { return _zones; }
+
+ /** @brief Get all slaves nodes */
+ VectorLong getSlaveNodes() const;
+ /** @brief Get all slaves cells */
+ VectorLong getSlaveCells() const;
+
+ /** @brief Set/unset friction flag everywhere */
void enableFriction( const bool &friction );
+ /** @brief Detect if friction on one of the contact zone */
bool hasFriction() const;
+ /** @brief Set/unset smoothing of normals flag everywhere */
void enableSmoothing( const bool &smoothing );
+ /** @brief Detect if smoothing of normals on one of the contact zone */
bool hasSmoothing() const;
- VectorLong getSlaveNodes() const;
+ /** @brief Get number of intersection points on all zones */
+ VectorLong getNumberOfIntersectionPoints() const;
- VectorLong getSlaveCells() const;
+ /** @brief Get number of intersection points on a contact zone */
+ VectorLong getNumberOfIntersectionPoints( const ASTERINTEGER &indexZone ) const;
+
+ /** @brief Builder from Fortran part */
+ bool build();
};
-/**
- * @typedef ContactNewPtr
- * @brief Pointeur intelligent vers un ContactNew
- */
using ContactNewPtr = std::shared_ptr< ContactNew >;
class FrictionNew : public ContactNew {
public:
- /**
- * @typedef FrictionNewPtr
- * @brief Pointeur intelligent vers un FrictionNew
- */
- typedef std::shared_ptr< FrictionNew > FrictionNewPtr;
-
- /**
- * @brief Constructeur
- */
+ using FrictionNewPtr = std::shared_ptr< FrictionNew >;
+
+ /** @brief No default constructor */
FrictionNew() = delete;
- /**
- * @brief Constructeur
- */
+ /** @brief Constructor with given name */
FrictionNew( const std::string name, const ModelPtr model )
: ContactNew( name, model, "CHAR_FROT" ) {};
- /**
- * @brief Constructeur
- */
+ /** @brief Constructor with automatic name */
FrictionNew( const ModelPtr model ) : FrictionNew( ResultNaming::getNewResultName(), model ) {};
+ /** @brief Builder from Fortran part */
bool build() {
AS_ASSERT( hasFriction() );
-
return ContactNew::build();
};
};
-/**
- * @typedef FrictionNewPtr
- * @brief Pointeur intelligent vers un FrictionNew
- */
using FrictionNewPtr = std::shared_ptr< FrictionNew >;
diff --git a/bibcxx/Contact/ContactPairing.cxx b/bibcxx/Contact/ContactPairing.cxx
index 60fa5ead89e..eaaec2d7c4d 100644
--- a/bibcxx/Contact/ContactPairing.cxx
+++ b/bibcxx/Contact/ContactPairing.cxx
@@ -24,62 +24,47 @@
#include "Messages/Messages.h"
-void ContactPairing::resizePairing( const int nbZoneCont ) {
- if ( nbZoneCont == 0 )
- raiseAsterError( "ContactZone vector is empty " );
- _nbPairs.resize( nbZoneCont );
- _listOfPairs.resize( nbZoneCont );
- _nbIntersectionPoints.resize( nbZoneCont );
- _slaveIntersectionPoints.resize( nbZoneCont );
-}
-
-ContactPairing::ContactPairing( const std::string name, const ContactNewPtr cont )
- : DataStructure( name, 8, "PAIRING_SD" ), _contDefi( cont ), _mesh( cont->getMesh() ) {
+ContactPairing::ContactPairing( const std::string name, const ContactNewPtr contDefi )
+ : DataStructure( name, 8, "PAIRING_SD" ),
+ _contDefi( contDefi ),
+ _mesh( contDefi->getMesh() ),
+ _verbosity( 1 ) {
if ( !_mesh || _mesh->isParallel() )
raiseAsterError( "Mesh is empty or is parallel " );
+ // Set verbosity
+ setVerbosity( contDefi->getVerbosity() );
+
+ // Create object for mesh coordinates
_currentCoordinates = std::make_shared< MeshCoordinatesField >( *( _mesh->getCoordinates() ) );
- // be sure that zones is not empty and get size of zones and resize
+ // Be sure that zones is not empty and get size of zones
int nbZoneCont = _contDefi->getNumberOfContactZones();
if ( nbZoneCont == 0 )
raiseAsterError( "ContactZone vector is empty " );
-
- // Resize pairing quantities
- resizePairing( nbZoneCont );
};
-ASTERBOOL ContactPairing::computeZone( ASTERINTEGER indexZone ) {
+void ContactPairing::setVerbosity( const ASTERINTEGER &level ) {
+ _verbosity = level;
+ _contDefi->setVerbosity( getVerbosity() );
+}
+
+ASTERBOOL ContactPairing::compute( ASTERINTEGER &indexZone ) {
if ( indexZone < 0 || indexZone >= _contDefi->getNumberOfContactZones() ) {
throw std::out_of_range( "The zone index should be between 0 and " +
std::to_string( _contDefi->getNumberOfContactZones() - 1 ) );
}
- CALL_JEMARQ();
+ ASTERBOOL returnValue;
+ // Get current zone
auto zone = _contDefi->getContactZone( indexZone );
AS_ASSERT( !zone->hasSmoothing() );
- // Get and define some input parameters
- VectorLong masterCells = zone->getMasterCells();
- VectorLong masterNodes = zone->getMasterNodes();
- VectorLong slaveCells = zone->getSlaveCells();
- ASTERINTEGER nbCellMaster = masterCells.size();
- ASTERINTEGER nbNodeMaster = masterNodes.size();
- ASTERINTEGER nbCellSlave = slaveCells.size();
- std::string pair_method;
-
- // Update the numbering for fortran
- std::for_each( masterCells.begin(), masterCells.end(), []( ASTERINTEGER &d ) { d += 1; } );
- std::for_each( masterNodes.begin(), masterNodes.end(), []( ASTERINTEGER &d ) { d += 1; } );
- std::for_each( slaveCells.begin(), slaveCells.end(), []( ASTERINTEGER &d ) { d += 1; } );
-
// Get pairing method
auto variant = zone->getPairingParameter()->getAlgorithm();
- if ( variant == PairingAlgo::Mortar ) {
- pair_method = ljust( "RAPIDE", 24, ' ' );
- } else {
+ if ( variant != PairingAlgo::Mortar ) {
AS_ABORT( "Not expected" );
}
@@ -89,43 +74,18 @@ ASTERBOOL ContactPairing::computeZone( ASTERINTEGER indexZone ) {
// Tolerance for pairing
ASTERDOUBLE pair_tole = 1e-8;
- // Set pairs numbers to 0
- ASTERINTEGER nb_pairs = 0;
-
- // Main routine for pairing
- auto pairs = JeveuxVectorLong( "&&LISTPAIRS" );
- auto nbInterPoints = JeveuxVectorLong( "&&NBPAIRS" );
- auto interSlavePoints = JeveuxVectorReal( "&&INTERSLPTS" );
-
- CALLO_APLCPGN( _mesh->getName(), _currentCoordinates->getName(), zone->getName(), pair_method,
- &pair_tole, &dist_pairing, &nbCellMaster, masterCells.data(), &nbCellSlave,
- slaveCells.data(), masterNodes.data(), &nbNodeMaster, &nb_pairs,
- ljust( pairs->getName(), 19, ' ' ), ljust( nbInterPoints->getName(), 19, ' ' ),
- ljust( interSlavePoints->getName(), 19, ' ' ) );
-
- // clearZone
- this->clearZone( indexZone );
-
- // fill the pairing quantities
- _nbPairs[indexZone] = nb_pairs;
- _listOfPairs[indexZone] = pairs->toVector();
- _nbIntersectionPoints[indexZone] = nbInterPoints->toVector();
- _slaveIntersectionPoints[indexZone] = interSlavePoints->toVector();
-
- // update numerotation
- std::transform( _listOfPairs[indexZone].begin(), _listOfPairs[indexZone].end(),
- _listOfPairs[indexZone].begin(),
- []( ASTERINTEGER &indexZone ) -> ASTERINTEGER { return --indexZone; } );
-
- CALL_JEDEMA();
+ // Pairing
+ zone->setVerbosity( getVerbosity() );
+ returnValue = zone->pairing( dist_pairing, pair_tole );
- return true;
+ return returnValue;
}
ASTERBOOL ContactPairing::compute() {
+
// Pairing
- for ( int i = 0; i < _contDefi->getNumberOfContactZones(); i++ ) {
- computeZone( i );
+ for ( ASTERINTEGER i = 0; i < _contDefi->getNumberOfContactZones(); i++ ) {
+ AS_ASSERT( compute( i ) );
}
// Build FED
@@ -134,60 +94,118 @@ ASTERBOOL ContactPairing::compute() {
return true;
}
-void ContactPairing::clearZone( ASTERINTEGER indexZone ) {
+void ContactPairing::clearPairing( const ASTERINTEGER &indexZone ) {
+ if ( indexZone < 0 || indexZone >= _contDefi->getNumberOfContactZones() ) {
+ throw std::out_of_range( "The zone index should be between 0 and " +
+ std::to_string( _contDefi->getNumberOfContactZones() - 1 ) );
+ }
- _listOfPairs[indexZone].clear();
- _nbIntersectionPoints[indexZone].clear();
- _slaveIntersectionPoints[indexZone].clear();
- _nbPairs.at( indexZone ) = 0;
+ _contDefi->clearPairing( indexZone );
}
-std::vector< std::pair< ASTERINTEGER, ASTERINTEGER > >
-ContactPairing::getListOfPairsOfZone( ASTERINTEGER indexZone ) const {
+VectorPairLong ContactPairing::getListOfPairs( const ASTERINTEGER &indexZone ) const {
- std::vector< std::pair< ASTERINTEGER, ASTERINTEGER > > tmp;
- ASTERINTEGER nbPairs = getNumberOfPairsOfZone( indexZone );
- tmp.reserve( nbPairs );
+ if ( indexZone < 0 || indexZone >= _contDefi->getNumberOfContactZones() ) {
+ throw std::out_of_range( "The zone index should be between 0 and " +
+ std::to_string( _contDefi->getNumberOfContactZones() - 1 ) );
+ }
- for ( auto iPair = 0; iPair < nbPairs; iPair++ ) {
- tmp.push_back( std::make_pair( _listOfPairs[indexZone][2 * iPair],
- _listOfPairs[indexZone][2 * iPair + 1] ) );
+ auto zone = _contDefi->getContactZone( indexZone );
+
+ return ( zone->getMeshPairing()->getListOfPairs() );
+}
+
+ASTERINTEGER ContactPairing::getNumberOfPairs( const ASTERINTEGER &indexZone ) const {
+ if ( indexZone < 0 || indexZone >= _contDefi->getNumberOfContactZones() ) {
+ throw std::out_of_range( "The zone index should be between 0 and " +
+ std::to_string( _contDefi->getNumberOfContactZones() - 1 ) );
}
+ return ( _contDefi->getContactZone( indexZone )->getMeshPairing()->getNumberOfPairs() );
+}
- return tmp;
+ASTERINTEGER ContactPairing::getNumberOfPairs() const {
+ ASTERINTEGER returnValue;
+ returnValue = 0;
+ for ( auto indexZone = 0; indexZone < _contDefi->getNumberOfContactZones(); indexZone++ ) {
+ returnValue += _contDefi->getMeshPairing( indexZone )->getNumberOfPairs();
+ }
+
+ return returnValue;
+};
+
+ASTERINTEGER ContactPairing::getNumberOfZones() const {
+ return _contDefi->getNumberOfContactZones();
}
-std::vector< std::pair< ASTERINTEGER, ASTERINTEGER > > ContactPairing::getListOfPairs() const {
+VectorPairLong ContactPairing::getListOfPairs() const {
- std::vector< std::pair< ASTERINTEGER, ASTERINTEGER > > tmp;
+ VectorPairLong returnValue;
ASTERINTEGER nbPairs = getNumberOfPairs();
- tmp.reserve( nbPairs );
- for ( int indexZone = 0; indexZone < _contDefi->getNumberOfContactZones(); indexZone++ ) {
- auto nbPairs = getNumberOfPairsOfZone( indexZone );
+ if ( nbPairs == 0 ) {
+ raiseAsterError( "No contact pairs: was the pairing performed correctly? " );
+ }
+
+ returnValue.reserve( nbPairs );
- for ( auto iPair = 0; iPair < nbPairs; iPair++ ) {
- tmp.push_back( std::make_pair( _listOfPairs[indexZone][2 * iPair],
- _listOfPairs[indexZone][2 * iPair + 1] ) );
- }
+ for ( ASTERINTEGER indexZone = 0; indexZone < _contDefi->getNumberOfContactZones();
+ indexZone++ ) {
+ VectorPairLong pairsOnZone = getListOfPairs( indexZone );
+ auto nbPairsZone = pairsOnZone.size();
+
+ for ( auto iPairZone = 0; iPairZone < nbPairsZone; iPairZone++ ) {
+ returnValue.push_back( pairsOnZone[iPairZone] );
+ };
}
- return tmp;
+ return returnValue;
}
-std::vector< VectorReal >
-ContactPairing::getSlaveIntersectionPoints( ASTERINTEGER indexZone ) const {
+VectorOfVectorsReal
+ContactPairing::getIntersectionPoints( ASTERINTEGER &indexZone,
+ const CoordinatesSpace coorSpace ) const {
- std::vector< VectorReal > ret;
- ASTERINTEGER nbPairs = getNumberOfPairsOfZone( indexZone );
- ret.reserve( nbPairs );
-
- auto iter = _slaveIntersectionPoints[indexZone].begin();
- for ( auto i = 0; i < nbPairs; i++ ) {
- ret.push_back( VectorReal( iter + 16 * i, iter + 16 * ( i + 1 ) ) );
+ VectorOfVectorsReal returnValue;
+ ASTERINTEGER nbPairs = getNumberOfPairs( indexZone );
+ if ( nbPairs == 0 ) {
+ raiseAsterError( "No contact pairs: was the pairing performed correctly? " );
}
+ returnValue.reserve( nbPairs );
+ for ( auto iPair = 0; iPair < nbPairs; iPair++ ) {
+ VectorOfVectorsReal interOnZone = _contDefi->getContactZone( indexZone )
+ ->getMeshPairing()
+ ->getIntersectionPoints( iPair, coorSpace );
+ ASTERINTEGER nbInter = _contDefi->getContactZone( indexZone )
+ ->getMeshPairing()
+ ->getNumberOfIntersectionPoints( iPair );
+ if ( nbInter != 0 ) {
+ VectorReal vectVale;
+ for ( auto iInter = 0; iInter < nbInter; iInter++ ) {
+ vectVale.insert( vectVale.end(), interOnZone[iInter].begin(),
+ interOnZone[iInter].end() );
+ };
+ returnValue.push_back( vectVale );
+ vectVale.clear();
+ }
+ }
+ return returnValue;
+}
- return ret;
+std::vector< VectorOfVectorsReal >
+ContactPairing::getIntersectionPoints( const CoordinatesSpace coorSpace ) const {
+
+ std::vector< VectorOfVectorsReal > returnValue;
+ const ASTERINTEGER nbZoneCont = _contDefi->getNumberOfContactZones();
+ if ( nbZoneCont == 0 )
+ raiseAsterError( "ContactZone vector is empty " );
+ returnValue.reserve( nbZoneCont );
+
+ for ( ASTERINTEGER iZone = 0; iZone < nbZoneCont; iZone++ ) {
+ VectorOfVectorsReal interSlave;
+ interSlave = ContactPairing::getIntersectionPoints( iZone, coorSpace );
+ returnValue.push_back( interSlave );
+ }
+ return returnValue;
}
ASTERINTEGER ContactPairing::getContCellIndx( const ContactAlgo contAlgo,
@@ -279,18 +297,17 @@ void ContactPairing::createVirtualElemForContact( const ASTERLOGICAL lAxis, cons
// Get pairing for this zone
auto surf2Volu = zone->getSlaveCellsSurfToVolu();
- auto iZonePairing = this->getListOfPairsOfZone( iZone );
- auto nbContPairZone = this->getNumberOfPairsOfZone( iZone );
+ auto listOfPairsZone = this->getListOfPairs( iZone );
+ auto nbPairsZone = this->getNumberOfPairs( iZone );
// Create vector of (virtual) contact cells for this zone
VectorPairLong listContTypeZone;
- listContTypeZone.reserve( nbContPairZone );
+ listContTypeZone.reserve( nbPairsZone );
// Loop on pairs in zone
- for ( int iPair = 0; iPair < nbContPairZone; iPair++ ) {
-
+ for ( int iPair = 0; iPair < nbPairsZone; iPair++ ) {
// Get pairing of current zone
- auto [slavCellNume, mastCellNume] = iZonePairing[iPair];
+ auto [slavCellNume, mastCellNume] = listOfPairsZone[iPair];
// Get cell slave to construct (is volumic cell for Nitsche)
auto slavCellUsedNume = slavCellNume;
@@ -374,8 +391,8 @@ void ContactPairing::createVirtualElemForOrphelanNodes(
auto lFric = zone->getFrictionParameter()->hasFriction();
// Get pairing for this zone
- auto iZonePairing = this->getListOfPairsOfZone( iZone );
- auto nbContPairZone = this->getNumberOfPairsOfZone( iZone );
+ auto listOfPairsZone = this->getListOfPairs( iZone );
+ auto nbPairsZone = this->getNumberOfPairs( iZone );
// Get slave cells on this zone
auto slaveCells = zone->getSlaveCells();
@@ -493,9 +510,6 @@ void ContactPairing::buildFiniteElementDescriptor() {
const ASTERINTEGER nbZoneCont = _contDefi->getNumberOfContactZones();
const ASTERINTEGER nbContPairTot = this->getNumberOfPairs();
- // Number of cells for each type of contact cell
- MapLong contactElemType;
-
// Create objets for nodes and cells
VectorOfVectorsLong listContElem;
listContElem.reserve( nbContPairTot );
@@ -509,6 +523,9 @@ void ContactPairing::buildFiniteElementDescriptor() {
// Index of current contact pair
ASTERINTEGER iContPair = 0;
+ // Object for number of cells for each type of contact cell
+ MapLong contactElemType;
+
// Create virtual elements for contact
createVirtualElemForContact( lAxis, nbZoneCont, contactElemType, meshConnectivity, listContElem,
listContType, iContPair, slaveNodePaired, slaveCellPaired );
@@ -544,6 +561,9 @@ void ContactPairing::buildFiniteElementDescriptor() {
// Clear map between zone and contact elements
_pair2Zone.clear();
+ // Clear map between index of global pair and index of local pair in zone
+ _globPairToLocaPair.clear();
+
// Add virtual element
for ( auto &[type, size] : contactElemType ) {
VectorLong contactElemZone;
@@ -564,6 +584,16 @@ void ContactPairing::buildFiniteElementDescriptor() {
ContactResFEDLiel->push_back( contactElemZone );
}
+ for ( ASTERINTEGER indexZone = 0; indexZone < nbZoneCont; indexZone++ ) {
+ if ( indexZone == 0 ) {
+ _globPairToLocaPair[indexZone] = 0;
+ } else {
+ auto zone = _contDefi->getContactZone( indexZone - 1 );
+ ASTERINTEGER nbPairs = zone->getMeshPairing()->getNumberOfPairs();
+ _globPairToLocaPair[indexZone] = _globPairToLocaPair[indexZone - 1] + nbPairs;
+ }
+ }
+
// Get parameters from standard model
auto paramToCopy = model->getFiniteElementDescriptor()->getParameters();
paramToCopy->updateValuePointer();
@@ -592,3 +622,23 @@ void ContactPairing::buildFiniteElementDescriptor() {
CALL_JEDEMA();
};
+
+VectorLong ContactPairing::getNumberOfIntersectionPoints() const {
+ VectorLong returnValue;
+ const ASTERINTEGER nbZoneCont = _contDefi->getNumberOfContactZones();
+ for ( ASTERINTEGER iZone = 0; iZone < nbZoneCont; iZone++ ) {
+ VectorLong nbInter;
+ nbInter = ContactPairing::getNumberOfIntersectionPoints( iZone );
+ returnValue.insert( returnValue.end(), nbInter.begin(), nbInter.end() );
+ }
+ return returnValue;
+}
+
+VectorLong ContactPairing::getNumberOfIntersectionPoints( ASTERINTEGER &indexZone ) const {
+
+ VectorLong returnValue;
+
+ returnValue = _contDefi->getMeshPairing( indexZone )->getNumberOfIntersectionPoints();
+
+ return returnValue;
+}
diff --git a/bibcxx/Contact/ContactPairing.h b/bibcxx/Contact/ContactPairing.h
index 766f89c6493..72151eed472 100644
--- a/bibcxx/Contact/ContactPairing.h
+++ b/bibcxx/Contact/ContactPairing.h
@@ -26,6 +26,7 @@
#include "Contact/ContactZone.h"
#include "DataFields/FieldOnNodes.h"
#include "DataStructures/DataStructure.h"
+#include "Meshes/MeshEnum.h"
// Description of a virtual contact cell
struct contCellType {
@@ -93,32 +94,26 @@ const struct contCellType contCellNits[contNitsType] = {
class ContactPairing : public DataStructure {
/** Datastructure for pairing */
private:
+ /** @brief Mesh */
+ BaseMeshPtr _mesh;
+
/** @brief Current coordinates of nodes */
MeshCoordinatesFieldPtr _currentCoordinates;
/** @brief Contact definition */
ContactNewPtr _contDefi;
- /** @brief Mesh */
- BaseMeshPtr _mesh;
-
- /** @brief Vector of number of pairs */
- VectorLong _nbPairs;
-
- /** @brief Vector of pairs */
- std::vector< VectorLong > _listOfPairs;
-
- /** @brief Vector of number of intersection points */
- std::vector< VectorLong > _nbIntersectionPoints;
+ /** @brief Finite element descriptor for virtual elements of contact */
+ FiniteElementDescriptorPtr _fed;
- /** @brief Vector of coordinates for intersection points */
- std::vector< VectorReal > _slaveIntersectionPoints;
+ /** @brief Level of verbosity */
+ ASTERINTEGER _verbosity;
/** @brief Map between pair and zone */
MapLong _pair2Zone;
- /** @brief Finite element descriptor for virtual elements of contact */
- FiniteElementDescriptorPtr _fed;
+ /** @brief Map between index of global pair and index of local pair in zone */
+ MapLong _globPairToLocaPair;
private:
/** @brief Resize pairing quantities */
@@ -151,14 +146,15 @@ class ContactPairing : public DataStructure {
const bool lAxis, const bool lFric );
public:
- using VectorLongPairs = std::vector< std::pair< ASTERINTEGER, ASTERINTEGER > >;
+ /** @brief No default constructor */
+ ContactPairing() = delete;
/** @brief Constructor with given name */
- ContactPairing( const std::string name, const ContactNewPtr cont );
+ ContactPairing( const std::string name, const ContactNewPtr contDefi );
/** @brief Constructor with automatic name */
- ContactPairing( const ContactNewPtr cont )
- : ContactPairing( ResultNaming::getNewResultName(), cont ) {};
+ ContactPairing( const ContactNewPtr contDefi )
+ : ContactPairing( ResultNaming::getNewResultName(), contDefi ) {};
/** @brief Get coordinates */
MeshCoordinatesFieldPtr getCoordinates() const { return _currentCoordinates; }
@@ -167,57 +163,66 @@ class ContactPairing : public DataStructure {
BaseMeshPtr getMesh() const { return _mesh; };
/** @brief Update coordinates */
- void updateCoordinates( FieldOnNodesRealPtr &disp ) {
+ void updateCoordinates( const FieldOnNodesRealPtr disp ) {
*_currentCoordinates = *( _mesh->getCoordinates() ) + *disp;
+ for ( auto indexZone = 0; indexZone < _contDefi->getNumberOfContactZones(); indexZone++ ) {
+ _contDefi->updateCoordinates( disp );
+ }
};
/** @brief Set coordinates */
- void setCoordinates( MeshCoordinatesFieldPtr &coor ) { _currentCoordinates = coor; };
+ void setCoordinates( const MeshCoordinatesFieldPtr coor ) {
+ _currentCoordinates = coor;
+ for ( auto indexZone = 0; indexZone < _contDefi->getNumberOfContactZones(); indexZone++ ) {
+ _contDefi->setCoordinates( coor );
+ }
+ };
/** @brief Compute pairing quantities of zone */
- ASTERBOOL computeZone( ASTERINTEGER indexZone );
+ ASTERBOOL compute( ASTERINTEGER &indexZone );
/** @brief Compute pairing quantities of all zones */
ASTERBOOL compute();
/** @brief Clear pairing quantities of zone */
- void clearZone( ASTERINTEGER indexZone );
+ void clearPairing( const ASTERINTEGER &indexZone );
/** @brief Clear pairing quantities for all zones */
- void clear() {
+ void clearPairing() {
for ( auto indexZone = 0; indexZone < _contDefi->getNumberOfContactZones(); indexZone++ ) {
- clearZone( indexZone );
+ clearPairing( indexZone );
}
};
- /** @brief Get number of all pairs */
- ASTERINTEGER getNumberOfPairs() const {
- return std::accumulate( _nbPairs.begin(), _nbPairs.end(), 0 );
- };
+ /** @brief Get number of zones */
+ ASTERINTEGER getNumberOfZones() const;
/** @brief Get number of pairs of zone */
- ASTERINTEGER getNumberOfPairsOfZone( ASTERINTEGER indexZone ) const {
- return _nbPairs[indexZone];
- }
+ ASTERINTEGER getNumberOfPairs( const ASTERINTEGER &indexZone ) const;
- /** @brief Get all list of pairs */
- VectorLongPairs getListOfPairs() const;
+ /** @brief Get number of pairs of all zones */
+ ASTERINTEGER getNumberOfPairs() const;
/** @brief Get list of pairs of zone */
- VectorLongPairs getListOfPairsOfZone( ASTERINTEGER indexZone ) const;
+ VectorPairLong getListOfPairs( const ASTERINTEGER &indexZone ) const;
- /** @brief Get slave intersection points of zone */
- std::vector< VectorReal > getSlaveIntersectionPoints( ASTERINTEGER indexZone ) const;
+ /** @brief Get list of pairs of all zones */
+ VectorPairLong getListOfPairs() const;
- /** @brief Get vector of number of intersection points on all zones */
- std::vector< VectorLong > getNumberOfIntersectionPoints() const {
- return _nbIntersectionPoints;
- };
+ /** @brief Get slave intersection points on all zones */
+ std::vector< VectorOfVectorsReal >
+ getIntersectionPoints( const CoordinatesSpace = CoordinatesSpace::Global ) const;
- /** @brief Get vector of slave intersection points on all zones */
- std::vector< VectorReal > getSlaveIntersectionPoints() const {
- return _slaveIntersectionPoints;
- };
+ /** @brief Get slave intersection points on contact zone */
+ VectorOfVectorsReal
+ getIntersectionPoints( ASTERINTEGER &indexZone,
+ const CoordinatesSpace = CoordinatesSpace::Global ) const;
+
+ /** @brief Get number of intersection points on all zones */
+ VectorLong getNumberOfIntersectionPoints() const;
+
+ /** @brief Get number of intersection points on contact zone */
+ VectorLong getNumberOfIntersectionPoints( ASTERINTEGER &indexZone ) const;
/** @brief Build Finite Element Descriptor from pairing */
void buildFiniteElementDescriptor();
@@ -227,6 +232,15 @@ class ContactPairing : public DataStructure {
/** @brief Get map between pair and zone */
MapLong pairsToZones() const { return _pair2Zone; };
+
+ /** @brief Get map between index of global pair and index of local pair in zone */
+ MapLong globPairToLocaPair() const { return _globPairToLocaPair; };
+
+ /** @brief Set verbosity */
+ void setVerbosity( const ASTERINTEGER &level );
+
+ /** @brief Get verbosity */
+ ASTERINTEGER getVerbosity() const { return _verbosity; }
};
using ContactPairingPtr = std::shared_ptr< ContactPairing >;
diff --git a/bibcxx/Contact/ContactZone.cxx b/bibcxx/Contact/ContactZone.cxx
index 4b5508863a8..7918a4d5496 100644
--- a/bibcxx/Contact/ContactZone.cxx
+++ b/bibcxx/Contact/ContactZone.cxx
@@ -24,6 +24,7 @@
#include "aster_fort_mesh.h"
+#include "Meshes/MeshPairing.h"
#include "Messages/Messages.h"
#include "ParallelUtilities/AsterMPI.h"
#include "Utilities/Tools.h"
@@ -36,289 +37,35 @@ ContactZone::ContactZone( const std::string name, const ModelPtr model )
_smoothing( false ),
_contParam( std::make_shared< ContactParameter >() ),
_fricParam( std::make_shared< FrictionParameter >() ),
- _pairParam( std::make_shared< PairingParameter >() ),
- _masterInverseConnectivity( JeveuxCollectionLong( getName() + ".CM" ) ),
- _slaveInverseConnectivity( JeveuxCollectionLong( getName() + ".CS" ) ),
- _masterNeighbors( JeveuxCollectionLong( getName() + ".MN" ) ),
- _slaveNeighbors( JeveuxCollectionLong( getName() + ".SN" ) ) {
- // model has to be mechanics
+ _pairParam( std::make_shared< PairingParameter >() ) {
if ( !_model->isMechanical() )
UTMESS( "F", "CONTACT1_2" );
-};
-
-void ContactZone::setSlaveGroupOfCells( const std::string &slave ) {
- if ( getMesh()->hasGroupOfCells( slave ) ) {
- _slaveNodes = getMesh()->getNodesFromCells( slave, false, true );
- _slaveCells = getMesh()->getCells( slave );
- _slaveGrp = slave;
- } else {
- throw std::runtime_error( "The given group " + slave + " doesn't exist in mesh" );
- }
-};
-
-void ContactZone::setMasterGroupOfCells( const std::string &master ) {
- if ( getMesh()->hasGroupOfCells( master ) ) {
- _masterNodes = getMesh()->getNodesFromCells( master, false, true );
- _masterCells = getMesh()->getCells( master );
- _masterGrp = master;
- } else {
- throw std::runtime_error( "The given group " + master + " doesn't exist in mesh" );
- }
-};
-
-void ContactZone::setExcludedSlaveGroupOfCells( const VectorString &excluded_slave ) {
- auto mesh = getMesh();
- for ( auto &name : excluded_slave ) {
- if ( !( getMesh()->hasGroupOfCells( name ) ) ) {
- throw std::runtime_error( "The group " + name + " doesn't exist in mesh" );
- }
-
- VectorLong sans_gr_i = mesh->getCells( name );
- auto it = _slaveCellsExcluded.end();
- _slaveCellsExcluded.insert( it, sans_gr_i.begin(), sans_gr_i.end() );
- }
- _slaveCells = set_difference( _slaveCells, _slaveCellsExcluded );
- AS_ASSERT( _slaveCells.size() > 0 );
- _slaveNodes = getMesh()->getNodesFromCells( _slaveCells );
+ _meshPairing = std::make_shared< MeshPairing >( getName(), model->getMesh() );
};
-void ContactZone::setExcludedSlaveGroupOfNodes( const VectorString &excluded_slave ) {
- auto mesh = getMesh();
- // build inverse connvectivity
- buildInverseConnectivity();
-
- for ( auto &name : excluded_slave ) {
- if ( !( getMesh()->hasGroupOfNodes( name ) ) ) {
- throw std::runtime_error( "The group " + name + " doesn't exist in mesh" );
- }
-
- VectorLong sans_gr_i = mesh->getNodes( name );
- for ( auto &node : sans_gr_i ) {
- auto cellsToExclude = this->getSlaveCellsFromNode( node );
- auto it = _slaveCellsExcluded.end();
- _slaveCellsExcluded.insert( it, cellsToExclude.begin(), cellsToExclude.end() );
- }
- }
+void ContactZone::setVerbosity( const ASTERINTEGER &level ) {
+ _verbosity = level;
+ _meshPairing->setVerbosity( getVerbosity() );
+}
- _slaveCells = set_difference( _slaveCells, _slaveCellsExcluded );
- AS_ASSERT( _slaveCells.size() > 0 );
- _slaveNodes = getMesh()->getNodesFromCells( _slaveCells );
-};
+bool ContactZone::pairing( ASTERDOUBLE &dist_pairing, ASTERDOUBLE &pair_tole ) {
+ return _meshPairing->compute( dist_pairing, pair_tole );
+}
bool ContactZone::build() {
- auto mesh = getMesh();
-
- // check that there is no nodes in common
- VectorLong commonNodes;
-
- if ( mesh->isParallel() ) {
-#ifdef ASTER_HAVE_MPI
- VectorLong slaveNodes_gl;
- AsterMPI::all_gather( _slaveNodes, slaveNodes_gl );
- commonNodes = set_intersection( slaveNodes_gl, _masterNodes );
-#endif
- } else {
- commonNodes = set_intersection( _slaveNodes, _masterNodes );
- }
- ASTERINTEGER size_inter_gl = commonNodes.size();
+ _meshPairing->initObjects();
- // share error
-#ifdef ASTER_HAVE_MPI
- if ( mesh->isParallel() ) {
- ASTERINTEGER size_inter_lc = size_inter_gl;
- size_inter_gl = AsterMPI::sum( size_inter_lc );
- }
-#endif
-
- if ( size_inter_gl > 0 ) {
+ auto hasCommonNodes = _meshPairing->hasCommonNodes();
+ if ( hasCommonNodes ) {
UTMESS( "F", "CONTACT1_1" );
}
// check mesh orientation (normals)
if ( checkNormals() ) {
- CALL_CHECKNORMALS( _model->getName().c_str(), ljust( _slaveGrp, 24, ' ' ).c_str(),
- ljust( _masterGrp, 24, ' ' ).c_str() );
+ _meshPairing->checkNormals( _model );
}
- // build inverse connvectivity
- AS_ASSERT( buildInverseConnectivity() );
-
- // build master and slave Cells Neighbors
- AS_ASSERT( buildCellsNeighbors() );
-
- // build surface to volume slave cell
- buildSlaveCellsVolu();
-
- return true;
-}
-
-ASTERBOOL ContactZone::buildInverseConnectivity() {
- // create master inverse connectivity
- ASTERINTEGER nbMaster = getMasterCells().size();
- std::string base( "G" );
-
- VectorLong masterCells;
- masterCells.reserve( _masterCells.size() );
-
- // shifting for fortran
- for ( auto cell : _masterCells )
- masterCells.push_back( cell + 1 );
-
- _masterInverseConnectivity->deallocate();
- CALL_CNCINV( getMesh()->getName().c_str(), masterCells.data(), &nbMaster, base.c_str(),
- _masterInverseConnectivity->getName().c_str() );
- _masterInverseConnectivity->build();
-
- // create slave inverse connectivity
- ASTERINTEGER nbSlave = _slaveCells.size();
-
- VectorLong slaveCells;
- slaveCells.reserve( _slaveCells.size() );
- for ( auto cell : _slaveCells )
- slaveCells.push_back( cell + 1 );
-
- _slaveInverseConnectivity->deallocate();
- CALL_CNCINV( getMesh()->getName().c_str(), slaveCells.data(), &nbSlave, base.c_str(),
- _slaveInverseConnectivity->getName().c_str() );
- _slaveInverseConnectivity->build();
-
return true;
}
-
-ASTERBOOL ContactZone::buildCellsNeighbors() {
-
- ASTERINTEGER ind_max, ind_min;
- // get master neighbors
- ASTERINTEGER nbMaster = getMasterCells().size();
- if ( nbMaster > 0 ) {
- ind_max = *std::max_element( _masterCells.begin(), _masterCells.end() ) + 1;
- ind_min = *std::min_element( _masterCells.begin(), _masterCells.end() ) + 1;
-
- std::string invmcn_name = ljust( _masterInverseConnectivity->getName(), 24, ' ' );
- std::string mn_name = ljust( _masterNeighbors->getName(), 24, ' ' );
-
- VectorLong masterCells;
- masterCells.reserve( _masterCells.size() );
- for ( auto cell : _masterCells )
- masterCells.push_back( cell + 1 );
-
- _masterNeighbors->deallocate();
- CALL_CNVOIS( getMesh()->getName(), masterCells.data(), invmcn_name, &nbMaster, &ind_min,
- &ind_max, mn_name );
-
- _masterNeighbors->build();
- }
-
- // get slave neighbors
-
- ASTERINTEGER nbSlave = _slaveCells.size();
- if ( nbSlave > 0 ) {
- ind_max = *std::max_element( _slaveCells.begin(), _slaveCells.end() ) + 1;
- ind_min = *std::min_element( _slaveCells.begin(), _slaveCells.end() ) + 1;
-
- std::string invscn_name = ljust( _slaveInverseConnectivity->getName(), 24, ' ' );
- std::string sn_name = ljust( _slaveNeighbors->getName(), 24, ' ' );
-
- VectorLong slaveCells;
- slaveCells.reserve( _slaveCells.size() );
- for ( auto cell : _slaveCells )
- slaveCells.push_back( cell + 1 );
- CALL_CNVOIS( getMesh()->getName(), slaveCells.data(), invscn_name, &nbSlave, &ind_min,
- &ind_max, sn_name );
-
- _slaveNeighbors->build();
- }
-
- return true;
-}
-
-void ContactZone::buildSlaveCellsVolu() {
- auto mesh = getMesh();
- auto nbCells = mesh->getNumberOfCells();
-
- auto invCon = mesh->getInverseConnectivity();
- invCon->build();
-
- auto exp = mesh->getConnectivityExplorer();
-
- for ( auto &cellId : _slaveCells ) {
- const auto cell = exp[cellId];
- VectorLong candidat;
- for ( const auto nodeId : cell ) {
- auto listCells = ( *invCon )[nodeId + 1]->toVector();
-
- std::for_each( listCells.begin(), listCells.end(), []( ASTERINTEGER &d ) { d -= 1; } );
-
- if ( candidat.empty() ) {
- candidat = listCells;
- } else {
- auto tmp = set_intersection( candidat, listCells );
- AS_ASSERT( !tmp.empty() );
- candidat = tmp;
- }
- }
-
- AS_ASSERT( candidat.size() == 2 );
- ASTERINTEGER cellVolu;
- if ( candidat[0] == cellId ) {
- cellVolu = candidat[1];
- } else {
- cellVolu = candidat[0];
- }
-
- _slavSurf2Volu[cellId] = cellVolu;
- }
-};
-
-VectorLong ContactZone::getMasterCellsFromNode( const ASTERINTEGER &i ) const {
- auto vct = ( *_masterInverseConnectivity )[i + 1]->toVector();
- std::transform( vct.begin(), vct.end(), vct.begin(), [this]( ASTERINTEGER k ) -> ASTERINTEGER {
- return k > 0 ? _masterCells[k - 1] : 0;
- } );
- return vct;
-}
-
-VectorLong ContactZone::getSlaveCellsFromNode( const ASTERINTEGER &i ) const {
- auto vct = ( *_slaveInverseConnectivity )[i + 1]->toVector();
- std::transform( vct.begin(), vct.end(), vct.begin(), [this]( ASTERINTEGER k ) -> ASTERINTEGER {
- return k > 0 ? _slaveCells[k - 1] : 0;
- } );
- return vct;
-}
-
-VectorLong ContactZone::getMasterCellNeighbors( const ASTERINTEGER &i ) const {
- ASTERINTEGER ind_min = *std::min_element( _masterCells.begin(), _masterCells.end() );
- ASTERINTEGER ind_max = *std::max_element( _masterCells.begin(), _masterCells.end() );
-
- if ( i < ind_min || i > ind_max )
- throw std::out_of_range( " the master cell's number should be"
- " between " +
- std::to_string( ind_min ) + " and " + std::to_string( ind_max ) );
-
- auto vct = ( *_masterNeighbors )[i - ind_min + 1]->toVector();
- vct.erase( std::remove_if( vct.begin(), vct.end(), []( ASTERINTEGER &i ) { return i == 0; } ),
- vct.end() );
- std::transform( vct.begin(), vct.end(), vct.begin(),
- []( ASTERINTEGER k ) -> ASTERINTEGER { return k - 1; } );
- return vct;
-}
-
-VectorLong ContactZone::getSlaveCellNeighbors( const ASTERINTEGER &i ) const {
-
- ASTERINTEGER ind_min = *std::min_element( _slaveCells.begin(), _slaveCells.end() );
- ASTERINTEGER ind_max = *std::max_element( _slaveCells.begin(), _slaveCells.end() );
-
- if ( i < ind_min || i > ind_max )
- throw std::out_of_range( " the slave cell's number should be"
- " between " +
- std::to_string( ind_min ) + " and " + std::to_string( ind_max ) );
-
- auto vct = ( *_slaveNeighbors )[i - ind_min + 1]->toVector();
- vct.erase( std::remove_if( vct.begin(), vct.end(), []( ASTERINTEGER &i ) { return i == 0; } ),
- vct.end() );
- std::transform( vct.begin(), vct.end(), vct.begin(),
- []( ASTERINTEGER k ) -> ASTERINTEGER { return k - 1; } );
- return vct;
-}
diff --git a/bibcxx/Contact/ContactZone.h b/bibcxx/Contact/ContactZone.h
index 12115de8ae4..f68aacae2ef 100644
--- a/bibcxx/Contact/ContactZone.h
+++ b/bibcxx/Contact/ContactZone.h
@@ -3,9 +3,9 @@
/**
* @file ContactZone.h
- * @brief Fichier entete de la class ContactZone
+ * @brief Header of class ContactZone
* @section LICENCE
- * Copyright (C) 1991 - 2023 EDF R&D www.code-aster.org
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
*
* This file is part of Code_Aster.
*
@@ -29,191 +29,150 @@
#include "Contact/ContactParameter.h"
#include "DataStructures/DataStructure.h"
#include "MemoryManager/JeveuxVector.h"
+#include "Meshes/MeshPairing.h"
#include "Modeling/Model.h"
#include "Supervis/ResultNaming.h"
class ContactZone : public DataStructure {
private:
- /** @brief Modele */
+ /** @brief Model */
ModelPtr _model;
/** @brief Level of verbosity */
ASTERINTEGER _verbosity;
- /** @brief Parameter for contact only */
+ /** @brief Parameters for contact */
ContactParameterPtr _contParam;
- /** @brief Parameter for friction only */
+ /** @brief Parameters for friction */
FrictionParameterPtr _fricParam;
- /** @brief Parameter for pairing only */
+ /** @brief Parameters for pairing */
PairingParameterPtr _pairParam;
- /** @brief Check direction of normal */
+ /** @brief Definition of pairing of two surfaces */
+ MeshPairingPtr _meshPairing;
+ /** @brief Check direction of normal */
bool _checkNormal;
/** @brief Smoothing of normal */
bool _smoothing;
- /** @brief List of master Cells */
- VectorLong _masterCells;
- /** @brief List of slave cells */
- VectorLong _slaveCells;
- /** @brief List of master nodes */
- VectorLong _masterNodes;
- /** @brief List of slave nodes */
- VectorLong _slaveNodes;
- /** @brief excluded elements of slave side for LAGRANGIEN */
- VectorLong _slaveCellsExcluded;
- /** @brief Master inverse connectivity */
- JeveuxCollectionLong _masterInverseConnectivity;
- /** @brief Slave inverse connectivity */
- JeveuxCollectionLong _slaveInverseConnectivity;
- /** @brief Master cells neighbors */
- JeveuxCollectionLong _masterNeighbors;
- /** @brief slave cells neighbors */
- JeveuxCollectionLong _slaveNeighbors;
- /** @brief Map between slave surfaciv and volumic cell */
- MapLong _slavSurf2Volu;
- /** @brief name of slave side */
- std::string _slaveGrp;
- /** @brief name of master side */
- std::string _masterGrp;
-
- /**
- * @brief Construct the inverse connectivity
- */
- ASTERBOOL buildInverseConnectivity();
- /**
- * @brief construct master/slave cells neighbors
- */
- ASTERBOOL buildCellsNeighbors();
-
- /**
- * @brief construct surface->volume slave cell
- */
- void buildSlaveCellsVolu();
public:
- /**
- * @typedef ContactZonePt
- * @brief Pointeur intelligent vers un ContactZone
- */
- typedef std::shared_ptr< ContactZone > ContactZonePtr;
- /**
- * @brief Constructeur
- */
+ using ContactZonePtr = std::shared_ptr< ContactZone >;
+
+ /** @brief No default constructor */
ContactZone() = delete;
- /**
- * @brief Constructeur
- */
+ /** @brief Constructor with given name */
ContactZone( const std::string name, const ModelPtr model );
- /**
- * @brief Constructeur
- */
+ /** @brief Constructor with automatic name */
ContactZone( const ModelPtr model ) : ContactZone( ResultNaming::getNewResultName(), model ) {};
+ /** @brief Get model */
ModelPtr getModel() const { return _model; }
+ /** @brief Get mesh */
BaseMeshPtr getMesh() const { return _model->getMesh(); }
- void setVerbosity( const ASTERINTEGER &level ) { _verbosity = level; }
+ /** @brief Set verbosity */
+ void setVerbosity( const ASTERINTEGER &level );
+ /** @brief Get verbosity */
ASTERINTEGER getVerbosity() const { return _verbosity; }
- bool build();
-
+ /** @brief Get parameters for contact */
ContactParameterPtr getContactParameter() const { return _contParam; };
+ /** @brief Get parameters for friction */
FrictionParameterPtr getFrictionParameter() const { return _fricParam; };
+ /** @brief Get parameters for pairing */
PairingParameterPtr getPairingParameter() const { return _pairParam; };
+ /** @brief Set parameters for contact */
void setContactParameter( const ContactParameterPtr contParam ) { _contParam = contParam; };
+ /** @brief Set parameters for friction */
void setFrictionParameter( const FrictionParameterPtr fricParam ) { _fricParam = fricParam; };
+ /** @brief Set parameters for pairing */
void setPairingParameter( const PairingParameterPtr pairParam ) { _pairParam = pairParam; };
- void setSlaveGroupOfCells( const std::string &slave );
-
- void setMasterGroupOfCells( const std::string &master );
-
- void setExcludedSlaveGroupOfCells( const VectorString &excluded_slave );
-
- void setExcludedSlaveGroupOfNodes( const VectorString &excluded_slave );
-
- VectorLong getExcludedSlaveCells() const { return _slaveCellsExcluded; };
-
- void checkNormals( const bool &checkNormal ) { _checkNormal = checkNormal; }
-
- bool checkNormals() const { return _checkNormal; }
-
- /**
- * @brief get master nodes
- */
- const VectorLong &getMasterNodes() const { return _masterNodes; };
-
- VectorLong &getMasterNodes() {
- return const_cast< VectorLong & >( std::as_const( *this ).getMasterNodes() );
+ /** @brief Set group of slave cells */
+ void setSlaveGroupOfCells( const std::string &groupName ) {
+ _meshPairing->setSlaveGroupOfCells( groupName );
}
- VectorLong getSlaveNodes() const { return _slaveNodes; }
-
- /**
- * @brief get master cells
- */
- const VectorLong &getMasterCells() const { return _masterCells; };
+ /** @brief Set group of master cells */
+ void setMasterGroupOfCells( const std::string &groupName ) {
+ _meshPairing->setMasterGroupOfCells( groupName );
+ }
+ /** @brief Get master cells */
+ const VectorLong &getMasterCells() const { return _meshPairing->getMasterCells(); };
VectorLong &getMasterCells() {
return const_cast< VectorLong & >( std::as_const( *this ).getMasterCells() );
}
- /**
- * @brief get slave cells
- */
- VectorLong getSlaveCells() const { return _slaveCells; }
+ /** @brief Get slave cells */
+ VectorLong getSlaveCells() const { return _meshPairing->getSlaveCells(); }
- VectorLong getMasterCellsFromNode( const ASTERINTEGER &i ) const;
+ /** @brief Set excluded groups of slave cells */
+ void setExcludedSlaveGroupOfCells( const VectorString &groupsName ) {
+ _meshPairing->setExcludedSlaveGroupOfCells( groupsName );
+ }
- VectorLong getSlaveCellsFromNode( const ASTERINTEGER &i ) const;
+ /** @brief Set excluded groups of slave nodes */
+ void setExcludedSlaveGroupOfNodes( const VectorString &groupsName ) {
+ _meshPairing->setExcludedSlaveGroupOfNodes( groupsName );
+ }
- VectorLong getMasterCellNeighbors( const ASTERINTEGER &i ) const;
+ /** @brief Set/get check normals */
+ void checkNormals( const bool &checkNormal ) { _checkNormal = checkNormal; }
+ bool checkNormals() const { return _checkNormal; }
- VectorLong getSlaveCellNeighbors( const ASTERINTEGER &i ) const;
+ /** @brief Get master nodes */
+ VectorLong getMasterNodes() const { return _meshPairing->getMasterNodes(); };
- auto getSlaveCellsSurfToVolu() const { return _slavSurf2Volu; };
+ /** @brief Get slave nodes */
+ VectorLong getSlaveNodes() const { return _meshPairing->getSlaveNodes(); };
+
+ /** @brief Get volume slave cells linked to all surfacic slave cells */
+ MapLong getSlaveCellsSurfToVolu() const { return _meshPairing->getSlaveCellsSurfToVolu(); };
+
+ /** @brief Get volume slave cell linked to a surfacic slave cells */
+ ASTERINTEGER getSlaveCellSurfToVolu( const ASTERINTEGER &cellIndex ) const {
+ return _meshPairing->getSlaveCellSurfToVolu( cellIndex );
+ };
- ASTERINTEGER getSlaveCellSurfToVolu( const ASTERINTEGER &i ) const {
- return _slavSurf2Volu.at( i );
+ /** @brief Set coordinates */
+ void setCoordinates( const MeshCoordinatesFieldPtr &coor ) {
+ _meshPairing->setCoordinates( coor );
};
- /**
- * @brief get master inverse connectivity as JeVeuxCollection
- */
- JeveuxCollectionLong getMasterInverseConnectivity() const { return _masterInverseConnectivity; }
- /**
- * @brief get slave inverse connectivity as JeVeuxCollection
- */
- JeveuxCollectionLong getSlaveInverseConnectivity() const { return _slaveInverseConnectivity; }
-
- /**
- * @brief get master neighbors
- */
- JeveuxCollectionLong getMasterNeighbors() const { return _masterNeighbors; }
- /**
- * @brief get slave neighbors
- */
- JeveuxCollectionLong getSlaveNeighbors() const { return _slaveNeighbors; }
+ /** @brief Update coordinates */
+ void updateCoordinates( const FieldOnNodesRealPtr &disp ) {
+ _meshPairing->updateCoordinates( disp );
+ };
+ /** @brief Set/unset friction for this zone */
void enableFriction( const bool &friction ) { _fricParam->enableFriction( friction ); };
+ /** @brief Detect if friction for this zone */
bool hasFriction() const { return _fricParam->hasFriction(); };
+ /** @brief Set/unset normal smoothing for this zone */
void enableSmoothing( const bool &smoothing ) { _smoothing = smoothing; };
+ /** @brief Detect if normal smoothing for this zone */
bool hasSmoothing() const { return _smoothing; };
+
+ /** @brief Compute pairing of zone */
+ bool pairing( ASTERDOUBLE &dist_pairing, ASTERDOUBLE &pair_tole );
+
+ /** @brief Get pairing of surface meshes */
+ MeshPairingPtr getMeshPairing() { return _meshPairing; };
+
+ /** @brief Builder from Fortran part */
+ bool build();
};
-/**
- * @typedef ContactZonePtr
- * @brief Pointeur intelligent vers un ContactZone
- */
-typedef std::shared_ptr< ContactZone > ContactZonePtr;
+using ContactZonePtr = std::shared_ptr< ContactZone >;
#endif /* CONTACT_ZONE_H_ */
diff --git a/bibcxx/DataFields/FieldBuilder.h b/bibcxx/DataFields/FieldBuilder.h
index db31ebe8e53..e98e1d230d9 100644
--- a/bibcxx/DataFields/FieldBuilder.h
+++ b/bibcxx/DataFields/FieldBuilder.h
@@ -6,7 +6,7 @@
* @brief Header of class FieldBuilder
* @author Nicolas Sellenet
* @section LICENCE
- * Copyright (C) 1991 - 2023 EDF R&D www.code-aster.org
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
*
* This file is part of Code_Aster.
*
@@ -40,176 +40,174 @@
* @author Nicolas Sellenet
*/
class FieldBuilder {
-private:
- std::map _mapGlobNume;
- std::map _mapLigrel;
-
- // I use them to debug easily mutiple creation
- // I don't use map directly to avoid to keep in memory unnecessary objects
- static std::set _setGlobNume;
- static std::set _setLigrel;
-
- /**
- * @brief Add a existing FiniteElementDescriptor in FieldBuilder
- */
- FiniteElementDescriptorPtr
- newFiniteElementDescriptor(const std::string &name, const BaseMeshPtr mesh) {
- if (_setLigrel.count(strip(name)) > 0) {
- raiseAsterError("LIGREL already exists: " + name);
- }
-
- auto curDesc = std::make_shared(name, mesh);
-
- addFiniteElementDescriptor(curDesc);
-
- return curDesc;
- };
-
- /**
- * @brief Add a existing EquationNumbering in FieldBuilder
- */
- EquationNumberingPtr newEquationNumbering(const std::string &name,
- const BaseMeshPtr mesh) {
- if (_setGlobNume.count(strip(name)) > 0) {
- raiseAsterError("NUME_EQUA already exists: " + name);
- }
-
- auto curDesc = std::make_shared(name);
- curDesc->setMesh(mesh);
-
- addEquationNumbering(curDesc);
-
- return curDesc;
- };
-
- /**
- * @brief Add a existing generalizedEquationNumbering in FieldBuilder
- */
- GeneralizedEquationNumberingPtr
- newGeneralizedEquationNumbering(const std::string &name) {
- AS_ABORT(name);
- if (_setGlobNume.count(strip(name)) > 0) {
- raiseAsterError("nume_equa_gene already exists: " + name);
- }
-
- auto curDesc = std::make_shared(name);
-
- return curDesc;
- };
-
-public:
- /**
- * @brief Constructor
- */
- FieldBuilder(){};
-
- /**
- * @brief Add a existing EquationNumbering in FieldBuilder
- */
- void addEquationNumbering(const EquationNumberingPtr &fond) {
- AS_ASSERT(fond);
-
- _mapGlobNume[strip(fond->getName())] = fond;
- _setGlobNume.insert(strip(fond->getName()));
- };
-
- /**
- * @brief Add a existing FiniteElementDescriptor in FieldBuilder
- */
- void addFiniteElementDescriptor(const FiniteElementDescriptorPtr &fed) {
- AS_ASSERT(fed);
-
- _mapLigrel[strip(fed->getName())] = fed;
- _setLigrel.insert(strip(fed->getName()));
- };
-
- void clear() {
- _mapGlobNume.clear();
- _mapLigrel.clear();
- };
-
- /**
- * @brief Build a FieldOnCells with a FiniteElementDescriptor
- */
- template
- std::shared_ptr>
- buildFieldOnCells(const std::string &name, const BaseMeshPtr mesh) {
- std::shared_ptr> field =
- std::make_shared>(name);
- field->updateValuePointers();
-
- const std::string ligrel = strip((*(*field)._reference)[0].toString());
-
- if (!ligrel.empty()) {
- auto curIter = _mapLigrel.find(ligrel);
- FiniteElementDescriptorPtr curDesc;
- if (curIter != _mapLigrel.end()) {
- curDesc = curIter->second;
- } else {
- curDesc = newFiniteElementDescriptor(ligrel, mesh);
- }
-
- field->setDescription(curDesc);
- }
- return field;
- };
-
- /**
- * @brief Build a ConstantFieldOnCells with a FiniteElementDescriptor
- */
- template
- std::shared_ptr>
- buildConstantFieldOnCells(const std::string &name, const BaseMeshPtr mesh) {
-
- std::shared_ptr> field =
- std::make_shared>(name, mesh);
- field->updateValuePointers();
-
- return field;
- };
-
- /**
- * @brief Build a FieldOnNodes with a EquationNumbering
- */
- template
- std::shared_ptr>
- buildFieldOnNodes(std::string name, const BaseMeshPtr mesh) {
- std::shared_ptr> field =
- std::make_shared>(name);
- field->updateValuePointers();
-
- const std::string globNume = strip((*(*field)._reference)[1].toString());
- AS_ASSERT(!globNume.empty());
-
- auto curIter = _mapGlobNume.find(globNume);
- EquationNumberingPtr curDesc;
- if (curIter != _mapGlobNume.end())
- curDesc = curIter->second;
- else {
- curDesc = newEquationNumbering(globNume, mesh);
- }
- field->setDescription(curDesc);
-
- return field;
- };
-
- std::vector getFiniteElementDescriptors() const {
- std::vector ret;
-
- for (auto &[name, fed] : _mapLigrel)
- ret.push_back(fed);
-
- return ret;
- };
-
- std::vector getEquationNumberings() const {
- std::vector ret;
-
- for (auto &[name, fnd] : _mapGlobNume)
- ret.push_back(fnd);
-
- return ret;
- };
+ private:
+ std::map< std::string, EquationNumberingPtr > _mapGlobNume;
+ std::map< std::string, FiniteElementDescriptorPtr > _mapLigrel;
+
+ // I use them to debug easily mutiple creation
+ // I don't use map directly to avoid to keep in memory unnecessary objects
+ static std::set< std::string > _setGlobNume;
+ static std::set< std::string > _setLigrel;
+
+ /**
+ * @brief Add a existing FiniteElementDescriptor in FieldBuilder
+ */
+ FiniteElementDescriptorPtr newFiniteElementDescriptor( const std::string &name,
+ const BaseMeshPtr mesh ) {
+ if ( _setLigrel.count( strip( name ) ) > 0 ) {
+ raiseAsterError( "LIGREL already exists: " + name );
+ }
+
+ auto curDesc = std::make_shared< FiniteElementDescriptor >( name, mesh );
+
+ addFiniteElementDescriptor( curDesc );
+
+ return curDesc;
+ };
+
+ /**
+ * @brief Add a existing EquationNumbering in FieldBuilder
+ */
+ EquationNumberingPtr newEquationNumbering( const std::string &name, const BaseMeshPtr mesh ) {
+ if ( _setGlobNume.count( strip( name ) ) > 0 ) {
+ raiseAsterError( "NUME_EQUA already exists: " + name );
+ }
+
+ auto curDesc = std::make_shared< EquationNumbering >( name );
+ curDesc->setMesh( mesh );
+
+ addEquationNumbering( curDesc );
+
+ return curDesc;
+ };
+
+ /**
+ * @brief Add a existing generalizedEquationNumbering in FieldBuilder
+ */
+ GeneralizedEquationNumberingPtr newGeneralizedEquationNumbering( const std::string &name ) {
+ AS_ABORT( name );
+ if ( _setGlobNume.count( strip( name ) ) > 0 ) {
+ raiseAsterError( "NUME_EQUA_GENE already exists: " + name );
+ }
+
+ auto curDesc = std::make_shared< GeneralizedEquationNumbering >( name );
+
+ return curDesc;
+ };
+
+ public:
+ /**
+ * @brief Constructor
+ */
+ FieldBuilder() {};
+
+ /**
+ * @brief Add a existing EquationNumbering in FieldBuilder
+ */
+ void addEquationNumbering( const EquationNumberingPtr &fond ) {
+ AS_ASSERT( fond );
+
+ _mapGlobNume[strip( fond->getName() )] = fond;
+ _setGlobNume.insert( strip( fond->getName() ) );
+ };
+
+ /**
+ * @brief Add a existing FiniteElementDescriptor in FieldBuilder
+ */
+ void addFiniteElementDescriptor( const FiniteElementDescriptorPtr &fed ) {
+ AS_ASSERT( fed );
+
+ _mapLigrel[strip( fed->getName() )] = fed;
+ _setLigrel.insert( strip( fed->getName() ) );
+ };
+
+ void clear() {
+ _mapGlobNume.clear();
+ _mapLigrel.clear();
+ };
+
+ /**
+ * @brief Build a FieldOnCells with a FiniteElementDescriptor
+ */
+ template < typename ValueType >
+ std::shared_ptr< FieldOnCells< ValueType > > buildFieldOnCells( const std::string &name,
+ const BaseMeshPtr mesh ) {
+ std::shared_ptr< FieldOnCells< ValueType > > field =
+ std::make_shared< FieldOnCells< ValueType > >( name );
+ field->updateValuePointers();
+
+ const std::string ligrel = strip( ( *( *field )._reference )[0].toString() );
+
+ if ( !ligrel.empty() ) {
+ auto curIter = _mapLigrel.find( ligrel );
+ FiniteElementDescriptorPtr curDesc;
+ if ( curIter != _mapLigrel.end() ) {
+ curDesc = curIter->second;
+ } else {
+ curDesc = newFiniteElementDescriptor( ligrel, mesh );
+ }
+
+ field->setDescription( curDesc );
+ }
+ return field;
+ };
+
+ /**
+ * @brief Build a ConstantFieldOnCells with a FiniteElementDescriptor
+ */
+ template < typename ValueType >
+ std::shared_ptr< ConstantFieldOnCells< ValueType > >
+ buildConstantFieldOnCells( const std::string &name, const BaseMeshPtr mesh ) {
+
+ std::shared_ptr< ConstantFieldOnCells< ValueType > > field =
+ std::make_shared< ConstantFieldOnCells< ValueType > >( name, mesh );
+ field->updateValuePointers();
+
+ return field;
+ };
+
+ /**
+ * @brief Build a FieldOnNodes with a EquationNumbering
+ */
+ template < typename ValueType >
+ std::shared_ptr< FieldOnNodes< ValueType > > buildFieldOnNodes( std::string name,
+ const BaseMeshPtr mesh ) {
+ std::shared_ptr< FieldOnNodes< ValueType > > field =
+ std::make_shared< FieldOnNodes< ValueType > >( name );
+ field->updateValuePointers();
+
+ const std::string globNume = strip( ( *( *field )._reference )[1].toString() );
+ AS_ASSERT( !globNume.empty() );
+
+ auto curIter = _mapGlobNume.find( globNume );
+ EquationNumberingPtr curDesc;
+ if ( curIter != _mapGlobNume.end() )
+ curDesc = curIter->second;
+ else {
+ curDesc = newEquationNumbering( globNume, mesh );
+ }
+ field->setDescription( curDesc );
+
+ return field;
+ };
+
+ std::vector< FiniteElementDescriptorPtr > getFiniteElementDescriptors() const {
+ std::vector< FiniteElementDescriptorPtr > ret;
+
+ for ( auto &[name, fed] : _mapLigrel )
+ ret.push_back( fed );
+
+ return ret;
+ };
+
+ std::vector< EquationNumberingPtr > getEquationNumberings() const {
+ std::vector< EquationNumberingPtr > ret;
+
+ for ( auto &[name, fnd] : _mapGlobNume )
+ ret.push_back( fnd );
+
+ return ret;
+ };
};
#endif /* FIELDBUILDER_H_ */
diff --git a/bibcxx/Meshes/BaseMesh.cxx b/bibcxx/Meshes/BaseMesh.cxx
index 12b7171f323..b208e845b65 100644
--- a/bibcxx/Meshes/BaseMesh.cxx
+++ b/bibcxx/Meshes/BaseMesh.cxx
@@ -283,6 +283,18 @@ JeveuxVectorLong BaseMesh::getCellsType() const {
return _cellsType;
};
+ASTERINTEGER BaseMesh::getCellDime( const ASTERINTEGER &index ) const {
+ ASTERINTEGER returnValue;
+
+ auto cellType = getCellType( index );
+ const std::string cata = "&CATA.TM.TMDIM";
+ JeveuxChar32 objName, charName;
+ CALLO_JEXNUM( objName, cata, &cellType );
+ CALLO_JENONU( objName, &returnValue );
+
+ return returnValue;
+};
+
std::string BaseMesh::getCellTypeName( const ASTERINTEGER &index ) const {
auto cellType = getCellType( index );
const std::string cata = "&CATA.TM.NOMTM";
@@ -317,6 +329,34 @@ bool BaseMesh::hasCellsOfType( const std::string typma ) const {
return false;
}
+bool BaseMesh::isSkin( const std::string groupName ) const {
+
+ if ( isParallel() ) {
+ auto meshDime = getDimension();
+ std::cout << "PARALLEL Mesh dime: " << meshDime << std::endl;
+ return true;
+ } else {
+ auto meshDime = getDimension();
+ std::cout << "Mesh dime: " << meshDime << std::endl;
+ if ( hasGroupOfCells( groupName ) ) {
+ const VectorLong cells = getCells( groupName );
+ const auto cellsType = getCellsType();
+ for ( auto &cellId : cells ) {
+ auto cellType = ( *cellsType )[cellId];
+ auto cellDime = getCellDime( cellType );
+ std::cout << "Cell dime: " << cellDime << std::endl;
+ if ( cellDime != ( meshDime - 1 ) ) {
+ return false;
+ }
+ }
+
+ } else {
+ throw std::runtime_error( "The given group " + groupName + " doesn't exist in mesh" );
+ }
+ }
+ return true;
+}
+
bool BaseMesh::build() {
_groupsOfNodes->build();
_groupsOfCells->build();
diff --git a/bibcxx/Meshes/BaseMesh.h b/bibcxx/Meshes/BaseMesh.h
index 805ff8a6dfa..aa3ab3863d3 100644
--- a/bibcxx/Meshes/BaseMesh.h
+++ b/bibcxx/Meshes/BaseMesh.h
@@ -213,10 +213,14 @@ class BaseMesh : public DataStructure, public ListOfTables {
JeveuxVectorLong getCellsType() const;
+ ASTERINTEGER getCellDime( const ASTERINTEGER &index ) const;
+
std::string getCellTypeName( const ASTERINTEGER &index ) const;
bool hasCellsOfType( const std::string ) const;
+ bool isSkin( const std::string groupName ) const;
+
/**
* @brief Recuperation de la dimension du maillage
*/
diff --git a/bibcxx/Meshes/Mesh.h b/bibcxx/Meshes/Mesh.h
index 16cce4dba8d..5d498a22455 100644
--- a/bibcxx/Meshes/Mesh.h
+++ b/bibcxx/Meshes/Mesh.h
@@ -138,6 +138,9 @@ class Mesh : public BaseMesh {
bool isQuadratic() const;
+ /** @brief Test if all cells in group are skin cells */
+ bool isSkin( const std::string groupName ) const;
+
/**
* @brief Read a Aster Mesh file
* @return retourne true si tout est ok
diff --git a/bibcxx/Meshes/MeshEnum.h b/bibcxx/Meshes/MeshEnum.h
new file mode 100644
index 00000000000..2bc476ded1b
--- /dev/null
+++ b/bibcxx/Meshes/MeshEnum.h
@@ -0,0 +1,37 @@
+#ifndef MESH_ENUM_H_
+#define MESH_ENUM_H_
+
+/**
+ * @file MeshEnum.h
+ * @brief Header of class MeshEnum
+ * @section LICENCE
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
+ *
+ * This file is part of Code_Aster.
+ *
+ * Code_Aster is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Code_Aster is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Code_Aster. If not, see .
+ */
+
+#include "astercxx.h"
+
+/* Define here Enum for mesh
+ *
+ * Thinkd to bind enum in python
+ */
+
+enum class PairingMethod { Fast, Legacy, BrutForce };
+
+enum class CoordinatesSpace { Slave, Global };
+
+#endif /* MESH_ENUM_H_ */
diff --git a/bibcxx/Meshes/MeshPairing.cxx b/bibcxx/Meshes/MeshPairing.cxx
new file mode 100644
index 00000000000..3e7c5a31fc0
--- /dev/null
+++ b/bibcxx/Meshes/MeshPairing.cxx
@@ -0,0 +1,676 @@
+/**
+ * @file MeshPairing.cxx
+ * @brief Implementation of MeshPairing class
+ * @section LICENCE
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
+ *
+ * This file is part of Code_Aster.
+ *
+ * Code_Aster is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Code_Aster is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Code_Aster. If not, see .
+ */
+
+#include "Meshes/MeshPairing.h"
+
+#include "aster_fort_ds.h"
+#include "aster_fort_mesh.h"
+
+#include "Messages/Messages.h"
+#include "Utilities/Tools.h"
+
+MeshPairing::MeshPairing( const std::string name, const BaseMeshPtr mesh )
+ : DataStructure( name, 8, "MESH_PAIRING" ),
+ _mesh( mesh ),
+ _masterInverseConnectivity( JeveuxCollectionLong( getName() + ".CM" ) ),
+ _slaveInverseConnectivity( JeveuxCollectionLong( getName() + ".CS" ) ),
+ _masterNeighbors( JeveuxCollectionLong( getName() + ".MN" ) ),
+ _slaveNeighbors( JeveuxCollectionLong( getName() + ".SN" ) ),
+ _verbosity( 1 ),
+ _slaveCellsGroup( " " ),
+ _masterCellsGroup( " " ),
+ _zoneHaveBeenDefined( false ),
+ _nbPairs( 0 ),
+ _method( PairingMethod::Fast ) {
+
+ _currentCoordinates = std::make_shared< MeshCoordinatesField >( *( _mesh->getCoordinates() ) );
+};
+
+// void MeshPairing::initPair() {
+// if ( !surfacesHasBeenDefined() ) {
+// throw std::runtime_error( "Surfaces are not defined." );
+// }
+// setPair( _slaveCellsGroup, _masterCellsGroup );
+// };
+
+void MeshPairing::setSlaveGroupOfCells( const std::string &groupName ) {
+ if ( getMesh()->hasGroupOfCells( groupName ) ) {
+ _slaveCellsGroup = groupName;
+ _slaveNodes = getMesh()->getNodesFromCells( groupName, false, true );
+ _slaveCells = getMesh()->getCells( groupName );
+ } else {
+ throw std::runtime_error( "The given group " + groupName + " doesn't exist in mesh" );
+ }
+};
+
+void MeshPairing::setMasterGroupOfCells( const std::string &groupName ) {
+ if ( getMesh()->hasGroupOfCells( groupName ) ) {
+ _masterCellsGroup = groupName;
+ _masterNodes = getMesh()->getNodesFromCells( groupName, false, true );
+ _masterCells = getMesh()->getCells( groupName );
+ } else {
+ throw std::runtime_error( "The given group " + groupName + " doesn't exist in mesh" );
+ }
+};
+
+void MeshPairing::setPair( const std::string &groupNameSlav, const std::string &groupNameMast ) {
+
+ MeshPairing::setMasterGroupOfCells( groupNameMast );
+ MeshPairing::setSlaveGroupOfCells( groupNameSlav );
+
+ this->initObjects();
+};
+
+ASTERBOOL
+MeshPairing::buildInverseConnectivity() {
+ // Create master inverse connectivity
+ ASTERINTEGER nbMaster = getMasterCells().size();
+ std::string base( "G" );
+
+ VectorLong masterCells;
+ masterCells.reserve( _masterCells.size() );
+
+ // Shifting for fortran
+ for ( auto cell : _masterCells )
+ masterCells.push_back( cell + 1 );
+
+ _masterInverseConnectivity->deallocate();
+ CALL_CNCINV( getMesh()->getName().c_str(), masterCells.data(), &nbMaster, base.c_str(),
+ _masterInverseConnectivity->getName().c_str() );
+ _masterInverseConnectivity->build();
+
+ // create slave inverse connectivity
+ ASTERINTEGER nbSlave = _slaveCells.size();
+
+ VectorLong slaveCells;
+ slaveCells.reserve( _slaveCells.size() );
+
+ // Shifting for fortran
+ for ( auto cell : _slaveCells )
+ slaveCells.push_back( cell + 1 );
+
+ _slaveInverseConnectivity->deallocate();
+ CALL_CNCINV( getMesh()->getName().c_str(), slaveCells.data(), &nbSlave, base.c_str(),
+ _slaveInverseConnectivity->getName().c_str() );
+ _slaveInverseConnectivity->build();
+
+ return true;
+}
+
+ASTERBOOL MeshPairing::buildCellsNeighbors() {
+
+ ASTERINTEGER ind_max, ind_min;
+
+ // Get master neighbors
+ ASTERINTEGER nbMaster = getMasterCells().size();
+ if ( nbMaster > 0 ) {
+ ind_max = *std::max_element( _masterCells.begin(), _masterCells.end() ) + 1;
+ ind_min = *std::min_element( _masterCells.begin(), _masterCells.end() ) + 1;
+
+ std::string invmcn_name = ljust( _masterInverseConnectivity->getName(), 24, ' ' );
+ std::string mn_name = ljust( _masterNeighbors->getName(), 24, ' ' );
+
+ VectorLong masterCells;
+ masterCells.reserve( _masterCells.size() );
+ for ( auto cell : _masterCells )
+ masterCells.push_back( cell + 1 );
+
+ _masterNeighbors->deallocate();
+ CALL_CNVOIS( getMesh()->getName(), masterCells.data(), invmcn_name, &nbMaster, &ind_min,
+ &ind_max, mn_name );
+
+ _masterNeighbors->build();
+ }
+
+ // Get slave neighbors
+ ASTERINTEGER nbSlave = getSlaveCells().size();
+ if ( nbSlave > 0 ) {
+ ind_max = *std::max_element( _slaveCells.begin(), _slaveCells.end() ) + 1;
+ ind_min = *std::min_element( _slaveCells.begin(), _slaveCells.end() ) + 1;
+
+ std::string invscn_name = ljust( _slaveInverseConnectivity->getName(), 24, ' ' );
+ std::string sn_name = ljust( _slaveNeighbors->getName(), 24, ' ' );
+
+ VectorLong slaveCells;
+ slaveCells.reserve( _slaveCells.size() );
+ for ( auto cell : _slaveCells )
+ slaveCells.push_back( cell + 1 );
+ CALL_CNVOIS( getMesh()->getName(), slaveCells.data(), invscn_name, &nbSlave, &ind_min,
+ &ind_max, sn_name );
+
+ _slaveNeighbors->build();
+ }
+
+ return true;
+}
+
+void MeshPairing::clearResult() {
+ _nbPairs = 0;
+ _pairs.clear();
+ _nbPoinInte.clear();
+ _poinInteSlav.clear();
+}
+
+ASTERBOOL MeshPairing::surfacesHasBeenDefined() {
+ ASTERBOOL returnValue;
+ returnValue = ( _slaveCellsGroup.size() != 0 && _masterCellsGroup.size() != 0 );
+ return returnValue;
+}
+
+ASTERBOOL MeshPairing::compute( ASTERDOUBLE &dist_pairing, ASTERDOUBLE &pair_tole ) {
+
+ CALL_JEMARQ();
+
+ // Get and define some input parameters
+ VectorLong masterCells = getMasterCells();
+ VectorLong masterNodes = getMasterNodes();
+ VectorLong slaveCells = getSlaveCells();
+ ASTERINTEGER nbCellMaster = masterCells.size();
+ ASTERINTEGER nbNodeMaster = masterNodes.size();
+ ASTERINTEGER nbCellSlave = slaveCells.size();
+ ASTERINTEGER verbosity = getVerbosity();
+ std::string mastConnexInveName = getMasterInverseConnectivityName();
+ std::string mastNeighName = getMasterNeighName();
+ std::string slavNeighName = getSlaveNeighName();
+
+ // Update the numbering for fortran
+ std::for_each( masterCells.begin(), masterCells.end(), []( ASTERINTEGER &d ) { d += 1; } );
+ std::for_each( masterNodes.begin(), masterNodes.end(), []( ASTERINTEGER &d ) { d += 1; } );
+ std::for_each( slaveCells.begin(), slaveCells.end(), []( ASTERINTEGER &d ) { d += 1; } );
+
+ // Set pairs numbers to 0
+ ASTERINTEGER nb_pairs = 0;
+
+ // Clear pairing results
+ this->clearResult();
+
+ // Method
+ ASTERINTEGER method;
+ if ( _method == PairingMethod::Fast ) {
+ method = 1;
+ } else if ( _method == PairingMethod::Legacy ) {
+ method = 2;
+ } else if ( _method == PairingMethod::BrutForce ) {
+ method = 3;
+ } else {
+ raiseAsterError( "Unknown method of pairing " );
+ }
+
+ // Main routine for pairing
+ CALLO_PAIRWRAP( &method, _mesh->getName(), _currentCoordinates->getName(), mastConnexInveName,
+ mastNeighName, slavNeighName, &pair_tole, &dist_pairing, &verbosity,
+ &nbCellMaster, masterCells.data(), &nbCellSlave, slaveCells.data(),
+ &nbNodeMaster, masterNodes.data(), &nb_pairs, getBasename() );
+
+ // Output JEVEUX objects
+ if ( !_jvPairs.exists() ) {
+ _jvPairs = JeveuxVectorLong( getPairsName() );
+ }
+ if ( !_jvNbInterPoints.exists() ) {
+ _jvNbInterPoints = JeveuxVectorLong( getNbInterName() );
+ }
+ if ( !_jvInterSlavePoints.exists() ) {
+ _jvInterSlavePoints = JeveuxVectorReal( getCoorInterName() );
+ }
+ _jvPairs->updateValuePointer();
+ _jvNbInterPoints->updateValuePointer();
+ _jvInterSlavePoints->updateValuePointer();
+
+ // Set output values
+ _nbPairs = nb_pairs;
+ _pairs = _jvPairs->toVector();
+ std::transform( _pairs.begin(), _pairs.end(), _pairs.begin(),
+ []( ASTERINTEGER &indexCell ) -> ASTERINTEGER { return --indexCell; } );
+ _nbPoinInte = _jvNbInterPoints->toVector();
+ _poinInteSlav = _jvInterSlavePoints->toVector();
+
+ CALL_JEDEMA();
+
+ return true;
+}
+
+VectorPairLong MeshPairing::getListOfPairs() const {
+
+ VectorPairLong returnValue;
+ ASTERINTEGER nbPairs = getNumberOfPairs();
+
+ if ( nbPairs == 0 ) {
+ throw std::runtime_error( "No pairs !" );
+ }
+
+ if ( _pairs.size() == 0 ) {
+ throw std::runtime_error( "No pairs from Fortran!" );
+ }
+
+ returnValue.reserve( nbPairs );
+
+ for ( auto iPair = 0; iPair < nbPairs; iPair++ ) {
+ returnValue.push_back( std::make_pair( _pairs[2 * iPair], _pairs[2 * iPair + 1] ) );
+ }
+
+ return returnValue;
+}
+
+// VectorOfVectorsReal MeshPairing::getIntersectionPoints( const ASTERINTEGER &indexPair,
+// const CoordinatesSpace coorSpace ) const
+// {
+
+// ASTERINTEGER nbPairs = getNumberOfPairs();
+// VectorOfVectorsReal returnValue;
+
+// if ( indexPair < 0 || indexPair >= nbPairs ) {
+// throw std::out_of_range( "The pair index should be between 0 and " +
+// std::to_string( nbPairs ) );
+// }
+
+// ASTERINTEGER nbInter = getNumberOfIntersectionPoints( indexPair );
+// VectorReal coorParaPoint;
+// coorParaPoint.reserve( 2 );
+// coorParaPoint.push_back( 0.0 );
+// coorParaPoint.push_back( 0.0 );
+
+// if ( nbInter != 0 ) {
+// returnValue.reserve( nbInter );
+// for ( auto iInter = 0; iInter < nbInter; iInter++ ) {
+// coorParaPoint[0] = _poinInteSlav[16 * ( indexPair ) + iInter];
+// coorParaPoint[1] = _poinInteSlav[16 * ( indexPair ) + iInter + 8];
+// returnValue.push_back( coorParaPoint );
+// }
+// }
+
+// return returnValue;
+// }
+
+ASTERINTEGER MeshPairing::getNumberOfIntersectionPoints( const ASTERINTEGER &indexPair ) const {
+
+ ASTERINTEGER nbPairs = getNumberOfPairs();
+
+ if ( indexPair < 0 || indexPair >= nbPairs ) {
+ throw std::out_of_range( "The pair index should be between 0 and " +
+ std::to_string( nbPairs ) );
+ }
+
+ return _nbPoinInte[indexPair];
+}
+
+VectorLong MeshPairing::getNumberOfIntersectionPoints() const {
+
+ ASTERINTEGER nbPairs = getNumberOfPairs();
+
+ VectorLong returnValue;
+
+ for ( auto indexPair = 0; indexPair < nbPairs; indexPair++ ) {
+ ASTERINTEGER nbInter = getNumberOfIntersectionPoints( indexPair );
+ returnValue.push_back( nbInter );
+ }
+ return returnValue;
+}
+
+VectorOfVectorsReal MeshPairing::getIntersectionPoints( const ASTERINTEGER &indexPair,
+ const CoordinatesSpace coorSpace ) const {
+
+ ASTERINTEGER nbPairs = getNumberOfPairs();
+
+ if ( indexPair < 0 || indexPair >= nbPairs ) {
+ throw std::out_of_range( "The pair index should be between 0 and " +
+ std::to_string( nbPairs ) );
+ }
+
+ ASTERINTEGER nbInter = getNumberOfIntersectionPoints( indexPair );
+
+ VectorOfVectorsReal returnValue;
+
+ if ( coorSpace == CoordinatesSpace::Global ) {
+ VectorReal coorGlobPoint;
+ coorGlobPoint.reserve( 3 );
+ coorGlobPoint.push_back( 0.0 );
+ coorGlobPoint.push_back( 0.0 );
+ coorGlobPoint.push_back( 0.0 );
+
+ // Objects for output
+ VectorReal poinInteReal;
+ poinInteReal.reserve( 3 * 8 );
+ CALLO_INTEPOINCOORWRAP( _mesh->getName(), _currentCoordinates->getName(), getBasename(),
+ &indexPair, poinInteReal.data() );
+
+ if ( nbInter == 0 ) {
+ throw std::out_of_range( "No intersection in pair " + std::to_string( indexPair ) );
+ } else {
+ returnValue.reserve( 3 * nbInter );
+ for ( auto iInter = 0; iInter < nbInter; iInter++ ) {
+ coorGlobPoint[0] = poinInteReal[3 * iInter];
+ coorGlobPoint[1] = poinInteReal[3 * iInter + 1];
+ coorGlobPoint[2] = poinInteReal[3 * iInter + 2];
+ returnValue.push_back( coorGlobPoint );
+ }
+ }
+ } else if ( coorSpace == CoordinatesSpace::Slave ) {
+
+ VectorReal coorParaPoint;
+ coorParaPoint.reserve( 2 );
+ coorParaPoint.push_back( 0.0 );
+ coorParaPoint.push_back( 0.0 );
+
+ if ( nbInter != 0 ) {
+ returnValue.reserve( nbInter );
+ for ( auto iInter = 0; iInter < nbInter; iInter++ ) {
+ coorParaPoint[0] = _poinInteSlav[16 * ( indexPair ) + iInter];
+ coorParaPoint[1] = _poinInteSlav[16 * ( indexPair ) + iInter + 8];
+ returnValue.push_back( coorParaPoint );
+ }
+ }
+ }
+ return returnValue;
+}
+
+ASTERDOUBLE MeshPairing::getIntersectionArea( const ASTERINTEGER &indexPair ) const {
+
+ ASTERINTEGER nbPairs = getNumberOfPairs();
+
+ if ( indexPair < 0 || indexPair >= nbPairs ) {
+ throw std::out_of_range( "The pair index should be between 0 and " +
+ std::to_string( nbPairs ) );
+ }
+
+ double coorPoint;
+ VectorReal poinInte;
+ ASTERDOUBLE inteArea = 0.0;
+
+ ASTERINTEGER nbInter = getNumberOfIntersectionPoints( indexPair );
+ if ( nbInter != 0 ) {
+ for ( auto iInter = 0; iInter < nbInter; iInter++ ) {
+ coorPoint = _poinInteSlav[16 * indexPair + iInter];
+ poinInte.push_back( coorPoint );
+ coorPoint = _poinInteSlav[16 * indexPair + 8 + iInter];
+ poinInte.push_back( coorPoint );
+ }
+ CALLO_INTECELLAREAWRAP( _mesh->getName(), &nbInter, poinInte.data(), &inteArea );
+ }
+ return inteArea;
+}
+
+std::vector< VectorReal > MeshPairing::getQuadraturePoints( const ASTERINTEGER &indexPair ) const {
+
+ std::vector< VectorReal > returnValue;
+
+ ASTERINTEGER nbPairs = getNumberOfPairs();
+ if ( indexPair < 0 || indexPair >= nbPairs ) {
+ throw std::out_of_range( "The pair index should be between 0 and " +
+ std::to_string( nbPairs ) );
+ }
+
+ VectorReal coorPoint;
+ coorPoint.reserve( 3 );
+ coorPoint.push_back( 0.0 );
+ coorPoint.push_back( 0.0 );
+ coorPoint.push_back( 0.0 );
+
+ ASTERINTEGER nbPoinQuad = 0;
+ VectorReal poinQuadReal;
+ poinQuadReal.reserve( 3 * 48 );
+ CALLO_QUADPOINCOORWRAP( _mesh->getName(), _currentCoordinates->getName(), getBasename(),
+ &indexPair, &nbPoinQuad, poinQuadReal.data() );
+
+ if ( nbPoinQuad != 0 ) {
+ returnValue.reserve( nbPoinQuad );
+ for ( long int iPoinQuad = 0; iPoinQuad < nbPoinQuad; iPoinQuad++ ) {
+ coorPoint[0] = poinQuadReal[3 * iPoinQuad];
+ coorPoint[1] = poinQuadReal[3 * iPoinQuad + 1];
+ coorPoint[2] = poinQuadReal[3 * iPoinQuad + 2];
+ returnValue.push_back( coorPoint );
+ }
+ }
+
+ return returnValue;
+}
+
+/** @brief Check for common nodes between slave and master side */
+ASTERBOOL MeshPairing::hasCommonNodes() const {
+
+ ASTERBOOL returnValue;
+ auto mesh = getMesh();
+
+ VectorLong commonNodes;
+ VectorLong masterNodes = _masterNodes;
+ VectorLong slaveNodes = _slaveNodes;
+ std::cout << "Master SIze<" << masterNodes.size() << ">" << std::endl;
+ for ( long int iNode = 0; iNode < masterNodes.size(); iNode++ ) {
+ std::cout << "Master node: " << masterNodes[iNode] << std::endl;
+ }
+ std::cout << "Slave SIze<" << slaveNodes.size() << ">" << std::endl;
+ for ( long int iNode = 0; iNode < slaveNodes.size(); iNode++ ) {
+ std::cout << "Slave node: " << slaveNodes[iNode] << std::endl;
+ }
+
+ if ( mesh->isParallel() ) {
+#ifdef ASTER_HAVE_MPI
+ VectorLong slaveNodes_gl;
+ AsterMPI::all_gather( _slaveNodes, slaveNodes_gl );
+ commonNodes = set_intersection( slaveNodes_gl, masterNodes );
+#endif
+ } else {
+ commonNodes = set_intersection( slaveNodes, masterNodes );
+ }
+
+ ASTERINTEGER size_inter_gl = commonNodes.size();
+
+ // share error
+#ifdef ASTER_HAVE_MPI
+ if ( mesh->isParallel() ) {
+ ASTERINTEGER size_inter_lc = size_inter_gl;
+ size_inter_gl = AsterMPI::sum( size_inter_lc );
+ }
+#endif
+ returnValue = false;
+ if ( size_inter_gl > 0 ) {
+ returnValue = true;
+ }
+
+ return returnValue;
+}
+
+VectorLong MeshPairing::getMasterCellsFromNode( const ASTERINTEGER &nodeIndex ) const {
+ auto vct = ( *_masterInverseConnectivity )[nodeIndex + 1]->toVector();
+ std::transform( vct.begin(), vct.end(), vct.begin(), [this]( ASTERINTEGER k ) -> ASTERINTEGER {
+ return k > 0 ? _masterCells[k - 1] : 0;
+ } );
+ return vct;
+}
+
+VectorLong MeshPairing::getSlaveCellsFromNode( const ASTERINTEGER &nodeIndex ) const {
+ auto vct = ( *_slaveInverseConnectivity )[nodeIndex + 1]->toVector();
+ std::transform( vct.begin(), vct.end(), vct.begin(), [this]( ASTERINTEGER k ) -> ASTERINTEGER {
+ return k > 0 ? _slaveCells[k - 1] : 0;
+ } );
+ return vct;
+}
+
+VectorLong MeshPairing::getMasterCellNeighbors( const ASTERINTEGER &cellIndex ) const {
+ ASTERINTEGER ind_min = *std::min_element( _masterCells.begin(), _masterCells.end() );
+ ASTERINTEGER ind_max = *std::max_element( _masterCells.begin(), _masterCells.end() );
+
+ if ( cellIndex < ind_min || cellIndex > ind_max )
+ throw std::out_of_range( " the master cell's number should be"
+ " between " +
+ std::to_string( ind_min ) + " and " + std::to_string( ind_max ) );
+
+ auto vct = ( *_masterNeighbors )[cellIndex - ind_min + 1]->toVector();
+ vct.erase( std::remove_if( vct.begin(), vct.end(),
+ []( ASTERINTEGER &cellIndex ) { return cellIndex == 0; } ),
+ vct.end() );
+ std::transform( vct.begin(), vct.end(), vct.begin(),
+ []( ASTERINTEGER k ) -> ASTERINTEGER { return k - 1; } );
+ return vct;
+}
+
+VectorLong MeshPairing::getSlaveCellNeighbors( const ASTERINTEGER &cellIndex ) const {
+
+ ASTERINTEGER ind_min = *std::min_element( _slaveCells.begin(), _slaveCells.end() );
+ ASTERINTEGER ind_max = *std::max_element( _slaveCells.begin(), _slaveCells.end() );
+
+ if ( cellIndex < ind_min || cellIndex > ind_max )
+ throw std::out_of_range( " the slave cell's number should be"
+ " between " +
+ std::to_string( ind_min ) + " and " + std::to_string( ind_max ) );
+
+ auto vct = ( *_slaveNeighbors )[cellIndex - ind_min + 1]->toVector();
+ vct.erase( std::remove_if( vct.begin(), vct.end(),
+ []( ASTERINTEGER &cellIndex ) { return cellIndex == 0; } ),
+ vct.end() );
+ std::transform( vct.begin(), vct.end(), vct.begin(),
+ []( ASTERINTEGER k ) -> ASTERINTEGER { return k - 1; } );
+ return vct;
+}
+
+ASTERBOOL MeshPairing::buildSlaveCellsVolu() {
+ auto mesh = getMesh();
+ auto nbCells = mesh->getNumberOfCells();
+
+ auto invCon = mesh->getInverseConnectivity();
+ invCon->build();
+
+ auto exp = mesh->getConnectivityExplorer();
+
+ for ( auto &cellId : _slaveCells ) {
+ const auto cell = exp[cellId];
+ VectorLong candidat;
+ for ( const auto nodeId : cell ) {
+ auto listCells = ( *invCon )[nodeId + 1]->toVector();
+
+ std::for_each( listCells.begin(), listCells.end(), []( ASTERINTEGER &d ) { d -= 1; } );
+
+ if ( candidat.empty() ) {
+ candidat = listCells;
+ } else {
+ auto tmp = set_intersection( candidat, listCells );
+ AS_ASSERT( !tmp.empty() );
+ candidat = tmp;
+ }
+ }
+
+ AS_ASSERT( candidat.size() == 2 );
+ ASTERINTEGER cellVolu;
+ if ( candidat[0] == cellId ) {
+ cellVolu = candidat[1];
+ } else {
+ cellVolu = candidat[0];
+ }
+
+ _slavSurf2Volu[cellId] = cellVolu;
+ }
+
+ return true;
+};
+
+void MeshPairing::setExcludedSlaveGroupOfCells( const VectorString &groupsName ) {
+ auto mesh = getMesh();
+ for ( auto &groupName : groupsName ) {
+ if ( !( getMesh()->hasGroupOfCells( groupName ) ) ) {
+ throw std::runtime_error( "The group " + groupName + " doesn't exist in mesh" );
+ }
+
+ VectorLong sans_gr_i = mesh->getCells( groupName );
+ auto it = _slaveCellsExcluded.end();
+ _slaveCellsExcluded.insert( it, sans_gr_i.begin(), sans_gr_i.end() );
+ }
+
+ _slaveCells = set_difference( _slaveCells, _slaveCellsExcluded );
+ AS_ASSERT( _slaveCells.size() > 0 );
+ _slaveNodes = getMesh()->getNodesFromCells( _slaveCells );
+};
+
+void MeshPairing::setExcludedSlaveGroupOfNodes( const VectorString &groupsName ) {
+ auto mesh = getMesh();
+
+ std::cout << "MESH - setExcludedSlaveGroupOfNodes <" << groupsName[0] << ">" << std::endl;
+
+ // Build inverse connectivity
+ AS_ASSERT( buildInverseConnectivity() );
+ std::cout << "MESH/nodes - Avant <" << _slaveNodes.size() << ">" << std::endl;
+ std::cout << "MESH - Avant <" << _slaveCells.size() << ">" << std::endl;
+
+ for ( auto &groupName : groupsName ) {
+ if ( !( getMesh()->hasGroupOfNodes( groupName ) ) ) {
+ throw std::runtime_error( "The group " + groupName + " doesn't exist in mesh" );
+ }
+
+ VectorLong sans_gr_i = mesh->getNodes( groupName );
+ std::cout << "Nombre de noeuds à exclure: " << sans_gr_i.size() << std::endl;
+ for ( auto &node : sans_gr_i ) {
+ auto cellsToExclude = this->getSlaveCellsFromNode( node );
+ std::cout << " Noeud: " << node << std::endl;
+ std::cout << " Cells : " << cellsToExclude.size() << std::endl;
+ auto it = _slaveCellsExcluded.end();
+ _slaveCellsExcluded.insert( it, cellsToExclude.begin(), cellsToExclude.end() );
+ }
+ }
+
+ std::cout << "MESH - Exclus <" << _slaveCellsExcluded.size() << ">" << std::endl;
+ std::cout << "MESH - Exclus <" << _slaveCellsExcluded[0] << ">" << std::endl;
+ _slaveCells = set_difference( _slaveCells, _slaveCellsExcluded );
+ std::cout << "MESH - Après <" << _slaveCells.size() << ">" << std::endl;
+ AS_ASSERT( _slaveCells.size() > 0 );
+ _slaveNodes = getMesh()->getNodesFromCells( _slaveCells );
+ std::cout << "MESH/nodes - Après <" << _slaveNodes.size() << ">" << std::endl;
+};
+
+ASTERBOOL MeshPairing::initObjects() {
+
+ _zoneHaveBeenDefined = true;
+
+ // // Désactivation verif (voir issue34073)
+ // // bool returnValue;
+ // // returnValue = getMesh()->isSkin( groupNameMast );
+ // // if ( !returnValue ) {
+ // // UTMESS( "F", "MESH4_2" );
+ // // }
+ // // returnValue = getMesh()->isSkin( groupNameSlav );
+ // // if ( !returnValue ) {
+ // // UTMESS( "F", "MESH4_2" );
+ // // }
+
+ // Build inverse connectivity
+ AS_ASSERT( buildInverseConnectivity() );
+
+ // Build master and slave cells neighbors
+ AS_ASSERT( buildCellsNeighbors() );
+
+ // Build surface to volume slave cell mapping
+ AS_ASSERT( buildSlaveCellsVolu() );
+
+ return true;
+}
+
+void MeshPairing::checkNormals( const ModelPtr _model ) const {
+ if ( _zoneHaveBeenDefined ) {
+ if ( _model->getMesh() == getMesh() ) {
+ CALL_CHECKNORMALS( _model->getName().c_str(),
+ ljust( getSlaveGroupOfCells(), 24, ' ' ).c_str(),
+ ljust( getMasterGroupOfCells(), 24, ' ' ).c_str() );
+ } else {
+ throw std::runtime_error( "Mesh is different in model" );
+ }
+
+ } else {
+ throw std::runtime_error( "Zone is undefined" );
+ }
+}
diff --git a/bibcxx/Meshes/MeshPairing.h b/bibcxx/Meshes/MeshPairing.h
new file mode 100644
index 00000000000..51bb978254c
--- /dev/null
+++ b/bibcxx/Meshes/MeshPairing.h
@@ -0,0 +1,284 @@
+#ifndef MESH_PAIRING_H_
+#define MESH_PAIRING_H_
+
+/**
+ * @file MeshPairing.h
+ * @brief Header of MeshPairing class
+ * @section LICENCE
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
+ *
+ * This file is part of Code_Aster.
+ *
+ * Code_Aster is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Code_Aster is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Code_Aster. If not, see .
+ */
+
+#include "astercxx.h"
+
+#include "DataFields/FieldOnNodes.h"
+#include "DataFields/MeshCoordinatesField.h"
+#include "DataStructures/DataStructure.h"
+#include "MemoryManager/JeveuxVector.h"
+#include "Meshes/Mesh.h"
+#include "Meshes/MeshEnum.h"
+#include "Supervis/ResultNaming.h"
+
+class MeshPairing : public DataStructure {
+ private:
+ /** @brief Mesh */
+ BaseMeshPtr _mesh;
+ /** @brief Current coordinates of nodes */
+ MeshCoordinatesFieldPtr _currentCoordinates;
+
+ /** @brief Flag when zone is defined */
+ bool _zoneHaveBeenDefined;
+ /** @brief Name of group for slave side */
+ std::string _slaveCellsGroup;
+ /** @brief Name of group for master side */
+ std::string _masterCellsGroup;
+ /** @brief List of master cells */
+ VectorLong _masterCells;
+ /** @brief List of slave cells */
+ VectorLong _slaveCells;
+ /** @brief List of master nodes */
+ VectorLong _masterNodes;
+ /** @brief List of slave nodes */
+ VectorLong _slaveNodes;
+ /** @brief List of excluded slave cells */
+ VectorLong _slaveCellsExcluded;
+
+ /** @brief Master inverse connectivity */
+ JeveuxCollectionLong _masterInverseConnectivity;
+ /** @brief Slave inverse connectivity */
+ JeveuxCollectionLong _slaveInverseConnectivity;
+ /** @brief Master cells neighbors */
+ JeveuxCollectionLong _masterNeighbors;
+ /** @brief Slave cells neighbors */
+ JeveuxCollectionLong _slaveNeighbors;
+
+ /** @brief Output JEVEUX objects from FORTRAN pairing */
+ JeveuxVectorLong _jvPairs;
+ JeveuxVectorLong _jvNbInterPoints;
+ JeveuxVectorReal _jvInterSlavePoints;
+
+ /** @brief Map between slave surfacic and volumic cell */
+ MapLong _slavSurf2Volu;
+
+ /** @brief Method of pairing */
+ PairingMethod _method;
+
+ /** @brief Level of verbosity */
+ ASTERINTEGER _verbosity;
+
+ /** @brief Number of pairs */
+ ASTERINTEGER _nbPairs;
+
+ /** @brief Vector of pairs */
+ VectorLong _pairs;
+
+ /** @brief Vector of number of intersection points */
+ VectorLong _nbPoinInte;
+
+ /** @brief Vector of coordinates for intersection points in slave parameteric space*/
+ VectorReal _poinInteSlav;
+
+ private:
+ /** @brief Get name of JEVEUX object for master inverse connectivity */
+ std::string getMasterInverseConnectivityName() const {
+ return ljust( getName() + ".CM", 24, ' ' );
+ }
+
+ /** @brief Get name of JEVEUX object for slave inverse connectivity */
+ std::string getSlaveInverseConnectivityName() const {
+ return ljust( getName() + ".CS", 24, ' ' );
+ }
+
+ /** @brief Get name of JEVEUX object for master neighbors */
+ std::string getMasterNeighName() const { return ljust( getName() + ".MN", 24, ' ' ); }
+
+ /** @brief Get name of JEVEUX object for slave neighbors */
+ std::string getSlaveNeighName() const { return ljust( getName() + ".SN", 24, ' ' ); }
+
+ /** @brief Get name of JEVEUX object for outputs*/
+ std::string getBasename() const { return ljust( getName(), 8, ' ' ); }
+
+ /** @brief Get name of JEVEUX object for pairs */
+ std::string getPairsName() const { return ljust( getBasename() + ".LISTPAIRS", 24, ' ' ); }
+
+ /** @brief Get name of JEVEUX object for number of intersection points */
+ std::string getNbInterName() const { return ljust( getBasename() + ".NBPOIN", 24, ' ' ); }
+
+ /** @brief Get name of JEVEUX object for coordinates of intersection points */
+ std::string getCoorInterName() const { return ljust( getBasename() + ".INTERSLPTS", 24, ' ' ); }
+
+ /** @brief Construct the inverse connectivity */
+ ASTERBOOL buildInverseConnectivity();
+
+ /** @brief Construct master/slave cells neighbors */
+ ASTERBOOL buildCellsNeighbors();
+
+ /** @brief Construct surface to volume slave cell mapping */
+ ASTERBOOL buildSlaveCellsVolu();
+
+ /** @brief Surface defined */
+ ASTERBOOL surfacesHasBeenDefined();
+
+ public:
+ using MeshPairingPtr = std::shared_ptr< MeshPairing >;
+
+ /** @brief No default constructor */
+ MeshPairing() = delete;
+
+ /** @brief Constructor with given name */
+ MeshPairing( const std::string name, const BaseMeshPtr mesh );
+
+ /** @brief Constructor with automatic name */
+ MeshPairing( const BaseMeshPtr mesh )
+ : MeshPairing( ResultNaming::getNewResultName(), mesh ) {};
+
+ /** @brief Initializations of datastructures defining pairing */
+ bool initObjects();
+
+ /** @brief Get mesh */
+ BaseMeshPtr getMesh() const { return _mesh; };
+
+ /** @brief Set verbosity */
+ void setVerbosity( const ASTERINTEGER &level ) { _verbosity = level; }
+
+ /** @brief Get verbosity */
+ ASTERINTEGER getVerbosity() const { return _verbosity; }
+
+ /** @brief Get coordinates */
+ MeshCoordinatesFieldPtr getCoordinates() const { return _currentCoordinates; }
+
+ /** @brief Update coordinates */
+ void updateCoordinates( const FieldOnNodesRealPtr &disp ) {
+ *_currentCoordinates = *( _mesh->getCoordinates() ) + *disp;
+ };
+
+ /** @brief Set coordinates */
+ void setCoordinates( const MeshCoordinatesFieldPtr &coor ) { _currentCoordinates = coor; };
+
+ /** @brief Set pair */
+ void setPair( const std::string &groupNameSlav, const std::string &groupNameMast );
+
+ /** @brief Init pair */
+ void initPair();
+
+ /** @brief Set slave cells */
+ void setSlaveGroupOfCells( const std::string &groupName );
+
+ /** @brief Set master cells */
+ void setMasterGroupOfCells( const std::string &groupName );
+
+ /** @brief Set excluded groups of slave cells */
+ void setExcludedSlaveGroupOfCells( const VectorString &groupsName );
+
+ /** @brief Set excluded groups of slave nodes */
+ void setExcludedSlaveGroupOfNodes( const VectorString &groupsName );
+
+ /** @brief Get name of group for slave cells */
+ std::string getSlaveGroupOfCells() const { return _slaveCellsGroup; }
+
+ /** @brief Get name of group for master cells */
+ std::string getMasterGroupOfCells() const { return _masterCellsGroup; }
+
+ /** @brief Get master cells*/
+ const VectorLong &getMasterCells() const { return _masterCells; };
+
+ /** @brief Get slave cells */
+ const VectorLong &getSlaveCells() const { return _slaveCells; };
+
+ /** @brief Get master nodes*/
+ const VectorLong &getMasterNodes() const { return _masterNodes; };
+ VectorLong &getMasterNodes() {
+ return const_cast< VectorLong & >( std::as_const( *this ).getMasterNodes() );
+ };
+
+ /** @brief Get slave nodes*/
+ const VectorLong &getSlaveNodes() const { return _slaveNodes; };
+ VectorLong &getSlaveNodes() {
+ return const_cast< VectorLong & >( std::as_const( *this ).getSlaveNodes() );
+ };
+
+ /** @brief Get master cells from a node (inverse connectivity) */
+ VectorLong getMasterCellsFromNode( const ASTERINTEGER &nodeIndex ) const;
+
+ /** @brief Get slave cells from a node (inverse connectivity) */
+ VectorLong getSlaveCellsFromNode( const ASTERINTEGER &nodeIndex ) const;
+
+ /** @brief Get neighbors of master cell */
+ VectorLong getMasterCellNeighbors( const ASTERINTEGER &cellIndex ) const;
+
+ /** @brief Get neighbors of slave cell */
+ VectorLong getSlaveCellNeighbors( const ASTERINTEGER &cellIndex ) const;
+
+ /** @brief Get volume slave cells linked to all surfacic slave cells */
+ MapLong getSlaveCellsSurfToVolu() const { return _slavSurf2Volu; };
+
+ /** @brief Get volume slave cells linked to one surfacic slave cells */
+ ASTERINTEGER getSlaveCellSurfToVolu( const ASTERINTEGER &cellIndex ) const {
+ return _slavSurf2Volu.at( cellIndex );
+ };
+
+ /** @brief Main subroutine for pairing */
+ ASTERBOOL compute( ASTERDOUBLE &dist_pairing, ASTERDOUBLE &pair_tole );
+
+ /** @brief Clear pairing result */
+ void clearResult();
+
+ /** @brief Get number of pairs */
+ ASTERBOOL hasPairs() const { return ( _nbPairs > 0 ); };
+
+ /** @brief Get number of pairs */
+ ASTERINTEGER getNumberOfPairs() const { return _nbPairs; };
+
+ /** @brief Get all list of pairs */
+ VectorPairLong getListOfPairs() const;
+
+ /** @brief Get pair */
+ MapLong getPair( const ASTERINTEGER &iPair );
+
+ /** @brief Get number of intersection points on all pairs */
+ VectorLong getNumberOfIntersectionPoints() const;
+
+ /** @brief Get number of intersection points of given pair */
+ ASTERINTEGER getNumberOfIntersectionPoints( const ASTERINTEGER &indexPair ) const;
+
+ /** @brief Get intersection points of given pair */
+ VectorOfVectorsReal
+ getIntersectionPoints( const ASTERINTEGER &indexPair,
+ const CoordinatesSpace = CoordinatesSpace::Global ) const;
+
+ /** @brief Get area of intersection of given pair */
+ ASTERDOUBLE getIntersectionArea( const ASTERINTEGER &indexPair ) const;
+
+ /** @brief Get number of quadrature points of given pair */
+ ASTERINTEGER getNumberOfQuadraturePoints( const ASTERINTEGER &indexPair ) const;
+
+ /** @brief Get quadrature points of given pair */
+ VectorOfVectorsReal getQuadraturePoints( const ASTERINTEGER &indexPair ) const;
+
+ /** @brief Check for common nodes between slave and master side */
+ ASTERBOOL hasCommonNodes() const;
+
+ /** @brief Check orientation of normals */
+ void checkNormals( const ModelPtr _model ) const;
+
+ /** @brief Set method */
+ void setMethod( const PairingMethod &method ) { _method = method; };
+};
+
+using MeshPairingPtr = std::shared_ptr< MeshPairing >;
+
+#endif
diff --git a/bibcxx/Messages/Messages.cxx b/bibcxx/Messages/Messages.cxx
index c9cf00748b4..18cff3a14d1 100644
--- a/bibcxx/Messages/Messages.cxx
+++ b/bibcxx/Messages/Messages.cxx
@@ -2,7 +2,7 @@
* @file Message.cxx
* @brief Fichier entete de la class Messages
* @section LICENCE
- * Copyright (C) 1991 - 2023 EDF R&D www.code-aster.org
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
*
* This file is part of Code_Aster.
*
@@ -24,10 +24,13 @@
#include "aster_fort_utils.h"
-void UTMESS( char *error, char *message ) { CALL_UTMESS( error, message ); }
-
-void UTMESS( const char *error, const char *message ) { UTMESS( (char *)error, (char *)message ); }
-
-void UTMESS( const std::string &error, const std::string &message ) {
- UTMESS( &error[0], &message[0] );
+void UTMESS( const std::string &typm, const std::string &idmess ) {
+ if ( typm == "A" || typm == "I" ) {
+ CALL_UTMESS( (char *)typm.c_str(), (char *)idmess.c_str() );
+ } else {
+ raiseAsterError( idmess );
+ }
}
+void UTMESS( char *typm, char *idmess ) { UTMESS( std::string( typm ), std::string( idmess ) ); }
+
+void UTMESS( const char *typm, const char *idmess ) { UTMESS( (char *)typm, (char *)idmess ); }
diff --git a/bibcxx/Messages/Messages.h b/bibcxx/Messages/Messages.h
index 3753fbbd179..386c6afee53 100644
--- a/bibcxx/Messages/Messages.h
+++ b/bibcxx/Messages/Messages.h
@@ -5,7 +5,7 @@
* @file Message.h
* @brief Fichier entete de la class Messages
* @section LICENCE
- * Copyright (C) 1991 - 2023 EDF R&D www.code-aster.org
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
*
* This file is part of Code_Aster.
*
@@ -25,12 +25,14 @@
#include "astercxx.h"
+#include "Supervis/Exceptions.h"
+
/* Encapsulation of utmess */
-void UTMESS( char *error, char *message );
+void UTMESS( char *typm, char *idmess );
-void UTMESS( const char *error, const char *message );
+void UTMESS( const char *typm, const char *idmess );
-void UTMESS( const std::string &error, const std::string &message );
+void UTMESS( const std::string &typm, const std::string &idmess );
#endif /* MESSAGES_H_ */
diff --git a/bibcxx/PythonBindings/ContactComputationInterface.cxx b/bibcxx/PythonBindings/ContactComputationInterface.cxx
index 443faa490e7..355764a8f0d 100644
--- a/bibcxx/PythonBindings/ContactComputationInterface.cxx
+++ b/bibcxx/PythonBindings/ContactComputationInterface.cxx
@@ -32,7 +32,7 @@ void exportContactComputationToPython( py::module_ &mod ) {
.def( py::init( &initFactoryPtr< ContactComputation, ContactNewPtr > ) )
.def( define_pickling< ContactComputation >() )
.def( "contactData", &ContactComputation::contactData, R"(
-Compute contact data (cf. MMCHML) as input to compute contact forces and matrices.
+Compute contact data as input to compute contact forces and matrices.
Arguments:
pairing (ContactPairing): pairing object
@@ -43,12 +43,30 @@ Compute contact data (cf. MMCHML) as input to compute contact forces and matrice
FieldOnCellsReal: contact data
)",
py::arg( "pairing" ), py::arg( "material" ), py::arg( "initial_contact" ) )
+ .def( "setVerbosity", &ContactComputation::setVerbosity, R"(
+Set level of verbosity
+0- without
+1- normal (default)
+2- detailled
+
+Arguments:
+ level (int) : level of verbosity
+)",
+ py::arg( "level" ) )
+ .def( "getVerbosity", &ContactComputation::getVerbosity, R"(
+Get level of verbosity
+0- without
+1- normal
+2- detailled
+
+Returns:
+ int: level of verbosity
+)" )
.def( "contactCoefficient", &ContactComputation::contactCoefficient, R"(
-Compute contact coefficient at the nodes of the slave surface based on values of COEF_CONT
+Compute contact coefficients at the nodes of the slave surface based on values of COEF_CONT
and COEF_FROT
Returns:
- FieldOnNodesReal: contact coefficient (= COEF_CONT)
- FieldOnNodesReal: friction coefficient (= COEF_FROT)
+ list[FieldOnNodesReal]: coefficients (COEF_CONT and COEF_FROT)
)" );
};
diff --git a/bibcxx/PythonBindings/ContactNewInterface.cxx b/bibcxx/PythonBindings/ContactNewInterface.cxx
index b81e5cf8eeb..4526bd29ebf 100644
--- a/bibcxx/PythonBindings/ContactNewInterface.cxx
+++ b/bibcxx/PythonBindings/ContactNewInterface.cxx
@@ -2,7 +2,7 @@
* @file ContactNewInterface.cxx
* @brief Interface python de ContactNew
* @section LICENCE
- * Copyright (C) 1991 - 2023 EDF R&D www.code-aster.org
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
*
* This file is part of Code_Aster.
*
@@ -33,25 +33,25 @@ void exportContactNewToPython( py::module_ &mod ) {
Return the model used in the contact definition
Returns:
- Model: model.
+ Model: model
)" )
.def( "getMesh", &ContactNew::getMesh, R"(
Return the mesh used in the contact definition
Returns:
- Mesh: mesh.
+ BaseMesh: mesh.
)" )
.def( "getFiniteElementDescriptor", &ContactNew::getFiniteElementDescriptor, R"(
Return the finite element descriptor to define virtual cells for Lagrange multipliers
Returns:
- FiniteElementDescriptor: fed.
+ FiniteElementDescriptor: finite element descriptor
)" )
.def( "getNumberOfContactZones", &ContactNew::getNumberOfContactZones, R"(
Return the number of contact zones used
Returns:
- inter: number of contact zones.
+ int: number of contact zones.
)" )
.def( "getContactZone", &ContactNew::getContactZone, R"(
Return the specified contact zone
diff --git a/bibcxx/PythonBindings/ContactPairingInterface.cxx b/bibcxx/PythonBindings/ContactPairingInterface.cxx
index 88218c48448..d1535c317a0 100644
--- a/bibcxx/PythonBindings/ContactPairingInterface.cxx
+++ b/bibcxx/PythonBindings/ContactPairingInterface.cxx
@@ -3,7 +3,7 @@
* @brief Interface python de ContactPairing
* @author Nicolas Sellenet
* @section LICENCE
- * Copyright (C) 1991 - 2023 EDF R&D www.code-aster.org
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
*
* This file is part of Code_Aster.
*
@@ -24,92 +24,170 @@
#include "PythonBindings/ContactPairingInterface.h"
#include "aster_pybind.h"
+// aslint: disable=C3006
void exportContactPairingToPython( py::module_ &mod ) {
- py::class_< ContactPairing, ContactPairingPtr, DataStructure >( mod, "ContactPairing" )
- .def( py::init( &initFactoryPtr< ContactPairing, std::string, ContactNewPtr > ) )
- .def( py::init( &initFactoryPtr< ContactPairing, ContactNewPtr > ) )
- .def( "getCoordinates", &ContactPairing::getCoordinates, R"(
+ py::class_< ContactPairing, ContactPairingPtr, DataStructure > class_( mod, "ContactPairing",
+ R"(
+Object to create contact pairing.)" );
+ class_.def( py::init( &initFactoryPtr< ContactPairing, std::string, ContactNewPtr > ) );
+ class_.def( py::init( &initFactoryPtr< ContactPairing, ContactNewPtr > ) );
+ class_.def( "getMesh", &ContactPairing::getMesh, R"(
+Mesh
+
+Returns:
+ BaseMesh: the mesh
+)" );
+ class_.def( "getCoordinates", &ContactPairing::getCoordinates, R"(
Coordinates of nodes used for pairing (almost always different from the intial mesh).
Returns:
- MeshCoordinatesFieldPtr: the coordinates field
-)" )
- .def( "updateCoordinates", &ContactPairing::updateCoordinates, R"(
+ MeshCoordinatesField: the coordinates field
+)" );
+ class_.def( "updateCoordinates", &ContactPairing::updateCoordinates, R"(
Update the mesh coordinates given a displacement field
+
+Arguments:
+ disp (FieldOnNodes) : field for displacement
+
)",
- ( py::arg( "disp" ) ) )
- .def( "setCoordinates", &ContactPairing::setCoordinates, R"(
+ ( py::arg( "disp" ) ) );
+ class_.def( "setCoordinates", &ContactPairing::setCoordinates, R"(
Set the mesh coordinates field
Arguments:
coordinates (MeshCoordinatesField) : coordinates to use for pairing
)",
- ( py::arg( "coordinates" ) ) )
- .def( "compute", &ContactPairing::compute, R"(
-Compute the pairing quantities associated with the zones
+ ( py::arg( "coordinates" ) ) );
+ class_.def( "compute", py::overload_cast<>( &ContactPairing::compute ),
+ R"(
+Compute the pairing quantities on all zones
Returns:
bool: True if the pairing quantities are updated appropriately
-)" )
- .def( "computeZone", &ContactPairing::computeZone, R"(
-Compute the pairing quantities associated with the zone zone_index
+)" );
+ class_.def( "compute", py::overload_cast< long int & >( &ContactPairing::compute ),
+ R"(
+Compute the pairing quantities on a zone
+
Arguments:
zone_index(int)
+
Returns:
bool: True if the pairing quantities are updated appropriately
)",
- ( py::arg( "zone_index" ) ) )
- .def( "getListOfPairsOfZone", &ContactPairing::getListOfPairsOfZone, R"(
-return list of pairs associated with the zone izone
+ ( py::arg( "zone_index" ) ) );
+ class_.def( "getNumberOfZones", &ContactPairing::getNumberOfZones, R"(
+Return the number of zones
+
+Returns:
+ int: number of zones
+)" );
+ class_.def( "getNumberOfPairs",
+ py::overload_cast<>( &ContactPairing::getNumberOfPairs, py::const_ ), R"(
+Return number of pairs on all zones
+
+Returns:
+ int: number of pairs
+)" );
+ class_.def(
+ "getNumberOfPairs",
+ py::overload_cast< const long int & >( &ContactPairing::getNumberOfPairs, py::const_ ),
+ R"(
+Return the number of pairs on a zone
+
Arguments:
zone_index(int)
Returns:
- List[List[int]]: List of pairs
+ int: number of pairs
)",
- ( py::arg( "zone_index" ) ) )
- .def( "getNumberOfPairsOfZone", &ContactPairing::getNumberOfPairsOfZone, R"(
-return number of pairs associated with the zone zone_index
+ ( py::arg( "zone_index" ) ) );
+ class_.def(
+ "getListOfPairs",
+ py::overload_cast< const long int & >( &ContactPairing::getListOfPairs, py::const_ ),
+ R"(
+Get list of contact pairs for a contact zone
+
Arguments:
zone_index(int)
+
Returns:
- int: number of pairs
+ list[tuple[int, int]]: list of contact pairs
)",
- ( py::arg( "zone_index" ) ) )
- .def( "getNumberOfPairs", &ContactPairing::getNumberOfPairs, R"(
-return the total number of pairs
+ ( py::arg( "zone_index" ) ) );
+ class_.def( "getListOfPairs",
+ py::overload_cast<>( &ContactPairing::getListOfPairs, py::const_ ),
+ R"(
+Get list of contact pairs on all zones
+
Returns:
- int: Total number of pairs
-)" )
- .def( "clearZone", &ContactPairing::clearZone, R"(
-clean all the paring quantities of zone zonde_index
+ list[tuple[int, int]]: list of contact pairs
+)" );
+ class_.def( "getIntersectionPoints",
+ py::overload_cast< ASTERINTEGER &, CoordinatesSpace >(
+ &ContactPairing::getIntersectionPoints, py::const_ ),
+ R"(
+Get the intersection points between master and slave cells
+
Arguments:
- zone_index(int)
+ zone_index(int) : index of zone
+ CoordinatesSpace (CoordinatesSpace): space to describe coordinates
+
Returns:
- bool: true if the pairing quantities are cleared
+ list[pair]: list of pair of coordinates of intersection points
)",
- ( py::arg( "zone_index" ) ) )
- .def( "getSlaveIntersectionPoints",
- py::overload_cast< ASTERINTEGER >( &ContactPairing::getSlaveIntersectionPoints,
- py::const_ ),
- R"(
-Get the intersection points beetween a master and slave cells in the parametric
-slave space. The maximum number of points is 8.
+ ( py::arg( "zone_index" ) ),
+ py::arg( "CoordinatesSpace" ) = CoordinatesSpace::Global );
+ class_.def( "getNumberOfIntersectionPoints",
+ py::overload_cast< ASTERINTEGER & >( &ContactPairing::getNumberOfIntersectionPoints,
+ py::const_ ),
+ R"(
+Get list of the number of intersection points beetween a master and slave cells.
Arguments:
zone_index(int) : index of zone
Returns:
- list[list]: list of list of intersection points (each intersection is of size 16)
+ list: list of number of intersection points
)",
- ( py::arg( "zone_index" ) ) )
- .def( "clear", &ContactPairing::clear, R"(
-clean all the paring quantities of all zones
+ ( py::arg( "zone_index" ) ) );
+ class_.def( "clearPairing", py::overload_cast<>( &ContactPairing::clearPairing ),
+ R"(
+Clean pairing for all zones
+
Returns:
bool: true if the pairing quantities are cleared
-)" )
- .def( "getFiniteElementDescriptor", &ContactPairing::getFiniteElementDescriptor, R"(
+)" );
+ class_.def( "clearPairing",
+ py::overload_cast< const ASTERINTEGER & >( &ContactPairing::clearPairing ),
+ R"(
+Clean pairing for a zone
+
+Arguments:
+ zone_index(int) : index of zone
+
+Returns:
+ bool: true if the pairing quantities are cleared
+)",
+ ( py::arg( "zone_index" ) ) );
+ class_.def( "setVerbosity", &ContactPairing::setVerbosity, R"(
+Set level of verbosity
+ 0 - without
+ 1 - normal (default)
+ 2 - detailled (text)
+
+Arguments:
+ level (integer): level of verbosity
+ )",
+ py::arg( "verbosity" ) );
+ class_.def( "getVerbosity", &ContactPairing::getVerbosity, R"(
+Get level of verbosity
+
+Returns:
+ integer: level of verbosity
+ )" );
+ class_.def( "getFiniteElementDescriptor", &ContactPairing::getFiniteElementDescriptor, R"(
Return Finite Element Descriptor for virtual cells from pairing.
Returns:
diff --git a/bibcxx/PythonBindings/ContactZoneInterface.cxx b/bibcxx/PythonBindings/ContactZoneInterface.cxx
index 93a7d6f6776..eeb809a25c3 100644
--- a/bibcxx/PythonBindings/ContactZoneInterface.cxx
+++ b/bibcxx/PythonBindings/ContactZoneInterface.cxx
@@ -2,7 +2,7 @@
* @file ContactZoneInterface.cxx
* @brief Interface python de ContactZone
* @section LICENCE
- * Copyright (C) 1991 - 2023 EDF R&D www.code-aster.org
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
*
* This file is part of Code_Aster.
*
@@ -26,166 +26,150 @@
void exportContactZoneToPython( py::module_ &mod ) {
- py::class_< ContactZone, ContactZone::ContactZonePtr, DataStructure >( mod, "ContactZone" )
+ py::class_< ContactZone, ContactZone::ContactZonePtr, DataStructure >( mod, "ContactZone", R"(
+Object to define a zone of contact.)" )
.def( py::init( &initFactoryPtr< ContactZone, std::string, ModelPtr > ) )
.def( py::init( &initFactoryPtr< ContactZone, ModelPtr > ) )
.def( "getModel", &ContactZone::getModel, R"(
Return the model used in the contact zone definition
Returns:
- Model: model.
- )" )
+ Model: model
+)" )
.def( "getMesh", &ContactZone::getMesh, R"(
Return the mesh used in the contact zone definition
Returns:
- BaseMesh: mesh.
- )" )
+ BaseMesh: mesh
+)" )
.def( "setVerbosity", &ContactZone::setVerbosity, R"(
-Set level of verbosity:
- 0- without
- 1- normal (default)
- 2- detailled
+Set level of verbosity
+0- without
+1- normal (default)
+2- detailled
Arguments:
- integer: level of verbosity
- )",
+ level (int) : level of verbosity
+)",
py::arg( "level" ) )
.def( "getVerbosity", &ContactZone::getVerbosity, R"(
-Get level of verbosity:
- 0- without
- 1- normal
- 2- detailled
+Get level of verbosity
+0- without
+1- normal
+2- detailled
Returns:
- integer: level of verbosity
- )" )
- .def_property( "hasFriction", &ContactZone::hasFriction, &ContactZone::enableFriction, R"(
-bool: enable or disable the use of friction.
+ int: level of verbosity
+)" )
+ .def_property( "hasFriction", &ContactZone::hasFriction, &ContactZone::enableFriction,
+ R"(
+Get status of friction
+
+Returns:
+ bool: friction or not
)" )
.def_property( "hasSmoothing", &ContactZone::hasSmoothing, &ContactZone::enableSmoothing,
R"(
-bool: enable or disable the use of smoothing.
- )" )
+Smoothing of normals
+
+Returns:
+ bool: smoothing or not
+ )" )
.def( "build", &ContactZone::build, R"(
Build and check internal objects
- )" )
+
+Returns:
+ bool: success or failure
+ )" )
.def( "setContactParameter", &ContactZone::setContactParameter, R"(
Set contact parameters defining method, coefficient...
Arguments:
- ContactParameter: contact parameters
- )",
- py::arg( "contact" ) )
+ contParam (ContactParameter) : contact parameters
+)",
+ py::arg( "contParam" ) )
.def( "getContactParameter", &ContactZone::getContactParameter, R"(
Get contact parameters defining method, coefficient...
Returns:
ContactParameter: contact parameters
- )" )
+)" )
.def( "setFrictionParameter", &ContactZone::setFrictionParameter, R"(
Set friction parameters defining method, coefficient...
Arguments:
- FrictionParameter: friction parameters
- )",
- py::arg( "friction" ) )
+ fricParam (FrictionParameter) : friction parameters
+)",
+ py::arg( "fricParam" ) )
.def( "getFrictionParameter", &ContactZone::getFrictionParameter, R"(
Get friction parameters defining method, coefficient...
Returns:
FrictionParameter: friction parameters
- )" )
+)" )
.def( "setPairingParameter", &ContactZone::setPairingParameter, R"(
Set pairing parameters defining algorithm, distance...
Arguments:
- PairingParameter: pairing parameters
- )",
- py::arg( "pairing" ) )
+ pairParam (PairingParameter) : pairing parameters
+)",
+ py::arg( "pairParam" ) )
.def( "getPairingParameter", &ContactZone::getPairingParameter, R"(
Get pairing parameters defining algorithm, distance...
Returns:
PairingParameter: pairing parameters
- )" )
+)" )
.def( "getSlaveNodes", &ContactZone::getSlaveNodes, R"(
Get slave's nodes index
Returns:
list[int]: slave's nodes index
- )" )
+)" )
.def( "getSlaveCells", &ContactZone::getSlaveCells, R"(
Get slave's cells index
Returns:
list[int]: slave's cells index
- )" )
+)" )
.def( "setSlaveGroupOfCells", &ContactZone::setSlaveGroupOfCells, R"(
Set slave's name of group of cells
Arguments:
- str: slave's name
- )",
+ slave_name (str) : name of group for slave cells
+)",
py::arg( "slave_name" ) )
.def( "setMasterGroupOfCells", &ContactZone::setMasterGroupOfCells, R"(
Set master's name of group of cells
Arguments:
- str: master's name
- )",
+ master_name (str) : name of group for master cells
+)",
py::arg( "master_name" ) )
- .def( "setExcludedSlaveGroupOfNodes", &ContactZone::setExcludedSlaveGroupOfNodes, R"(
+ .def( "setExcludedSlaveGroupOfNodes", &ContactZone::setExcludedSlaveGroupOfNodes,
+ R"(
Set excluded groups of nodes on slave side
Arguments:
- str: excluded groups' names
- )",
- py::arg( "groups" ) )
+ nodeGroupsName (str) : excluded groups' names
+ )",
+ py::arg( "nodeGroupsName" ) )
.def( "setExcludedSlaveGroupOfCells", &ContactZone::setExcludedSlaveGroupOfCells, R"(
Set excluded groups of cells on slave side
Arguments:
- str: excluded groups' names
- )",
- py::arg( "groups" ) )
- .def( "getExcludedSlaveCells", &ContactZone::getExcludedSlaveCells, R"(
-Get excluded groups of cells on slave side
+ cellGroupsName (str) : excluded groups' names
+ )",
+ py::arg( "cellGroupsName" ) )
+ .def( "getMeshPairing", &ContactZone::getMeshPairing, R"(
+Get pairing of surface meshes
Returns:
- str: excluded groups' names
+ MeshPairing: mesh pairing
)" )
.def_property( "checkNormals",
py::overload_cast<>( &ContactZone::checkNormals, py::const_ ),
py::overload_cast< const bool & >( &ContactZone::checkNormals ), R"(
- bool: Attribute that holds the checking of outwards normals.
- )" )
- .def( "getMasterCellsFromNode", &ContactZone::getMasterCellsFromNode, R"(
-Get the master cells associtaed with a node number
-
-Arguments:
- int: node number
- )",
- py::arg( "node_number" ) )
- .def( "getSlaveCellsFromNode", &ContactZone::getSlaveCellsFromNode, R"(
-Get the slave cells associtaed with a node number
-
-Arguments:
- int: node number
- )",
- py::arg( "node_number" ) )
- .def( "getMasterCellNeighbors", &ContactZone::getMasterCellNeighbors, R"(
-Get the master cells in the neighbor of a given master cell number
-
-Arguments:
- int: master cell number
- )",
- py::arg( "cell_number" ) )
- .def( "getSlaveCellNeighbors", &ContactZone::getSlaveCellNeighbors, R"(
-Get the slave cells in the neighbor of a given slave cell number
-
-Arguments:
- int: slave cell number
- )",
- py::arg( "cell_number" ) );
+bool: attribute that holds the checking of outwards normals.
+ )" );
};
diff --git a/bibcxx/PythonBindings/LibAster.cxx b/bibcxx/PythonBindings/LibAster.cxx
index 83dabfd1201..9c8aad02121 100644
--- a/bibcxx/PythonBindings/LibAster.cxx
+++ b/bibcxx/PythonBindings/LibAster.cxx
@@ -123,6 +123,7 @@
#include "PythonBindings/MeshCoordinatesFieldInterface.h"
#include "PythonBindings/MeshEntitiesInterface.h"
#include "PythonBindings/MeshInterface.h"
+#include "PythonBindings/MeshPairingInterface.h"
#include "PythonBindings/MeshesMappingInterface.h"
#include "PythonBindings/ModalBasisInterface.h"
#include "PythonBindings/ModeResultInterface.h"
@@ -234,6 +235,7 @@ PYBIND11_MODULE( libaster, mod ) {
exportContactParameterToPython( mod );
exportContactNewToPython( mod );
exportContactZoneToPython( mod );
+ exportMeshPairingToPython( mod );
exportContactPairingToPython( mod );
exportContactComputationToPython( mod );
exportBaseAssemblyMatrixToPython( mod );
diff --git a/bibcxx/PythonBindings/MeshPairingInterface.cxx b/bibcxx/PythonBindings/MeshPairingInterface.cxx
new file mode 100644
index 00000000000..0338467f4d7
--- /dev/null
+++ b/bibcxx/PythonBindings/MeshPairingInterface.cxx
@@ -0,0 +1,250 @@
+/**
+ * @file ContactZoneInterface.cxx
+ * @brief Interface python de ContactZone
+ * @section LICENCE
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
+ *
+ * This file is part of Code_Aster.
+ *
+ * Code_Aster is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Code_Aster is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Code_Aster. If not, see .
+ */
+
+#include "PythonBindings/MeshPairingInterface.h"
+
+#include "aster_pybind.h"
+// aslint: disable=C3006
+
+void exportMeshPairingToPython( py::module_ &mod ) {
+
+ py::class_< MeshPairing, MeshPairingPtr, DataStructure > class_( mod, "MeshPairing", R"(
+Object to create a pairing operator between two meshed surfaces.)" );
+ py::enum_< CoordinatesSpace >( mod, "CoordinatesSpace", R"(
+Type of coordinates: Slave or Global.)" )
+ .value( "Slave", CoordinatesSpace::Slave )
+ .value( "Global", CoordinatesSpace::Global )
+ .export_values();
+ class_.def( py::init( &initFactoryPtr< MeshPairing, std::string, BaseMeshPtr > ) );
+ class_.def( py::init( &initFactoryPtr< MeshPairing, BaseMeshPtr > ) );
+ class_.def( "getNumberOfPairs", &MeshPairing::getNumberOfPairs, R"(
+Get number of pairs
+
+Returns:
+ integer: number of pairs
+ )" );
+ class_.def( "getListOfPairs", &MeshPairing::getListOfPairs, R"(
+Get pairs
+
+Returns:
+ list: pairs (slave-master)
+ )" );
+ class_.def( "getNumberOfIntersectionPoints",
+ py::overload_cast< const ASTERINTEGER & >(
+ &MeshPairing::getNumberOfIntersectionPoints, py::const_ ),
+ R"(
+Get number of intersection points
+
+Arguments:
+ indexPair (integer): index of pair
+
+Returns:
+ integer: number of intersection points
+ )",
+ py::arg( "indexPair" ) );
+ class_.def(
+ "getIntersectionArea",
+ py::overload_cast< const ASTERINTEGER & >( &MeshPairing::getIntersectionArea, py::const_ ),
+ R"(
+Compute intersection of area
+
+Arguments:
+ indexPair (integer): index of pair
+
+Returns:
+ double: area of intersection
+ )",
+ py::arg( "indexPair" ) );
+ class_.def( "getNumberOfIntersectionPoints",
+ py::overload_cast<>( &MeshPairing::getNumberOfIntersectionPoints, py::const_ ),
+ R"(
+ Get number of intersection points of all pairs
+
+ Returns:
+ list: number of intersection points
+ )" );
+ class_.def( "setPair", &MeshPairing::setPair, R"(
+ Set pair of meshed surfaces
+
+ Arguments:
+ groupNameSlav (str): slave's name
+ groupNameMast (str): master's name
+ )",
+ py::arg( "groupNameSlav" ), py::arg( "groupNameMast" ) );
+ class_.def( "compute", &MeshPairing::compute, R"(
+Compute pairing
+
+Arguments:
+ dist_pairing (real): tolerance from DIST_RATIO (projection outside cell)
+ pair_tole (real): tolerance for pairing
+ )",
+ py::arg( "dist_pairing" ) = -1.0, py::arg( "pair_tole" ) = 1.E-8 );
+ class_.def( "updateCoordinates", &MeshPairing::updateCoordinates, R"(
+Update coordinates of nodes
+
+Arguments:
+ disp (FieldOnNodesReal): nodal field of displacement
+ )",
+ py::arg( "disp" ) );
+ class_.def( "setVerbosity", &MeshPairing::setVerbosity, R"(
+Set level of verbosity
+ 0 - without
+ 1 - normal (default)
+ 2 - detailled (text)
+
+Arguments:
+ level (integer): level of verbosity
+ )",
+ py::arg( "level" ) );
+ class_.def( "getIntersectionPoints", &MeshPairing::getIntersectionPoints, R"(
+Get coordinates of intersection points for a given pair
+
+Arguments:
+ indexPair (integer): index of pair
+ CoordinatesSpace (CoordinatesSpace): space to describe coordinates
+
+Returns:
+ list[list]: coordinates in given space
+ )",
+ py::arg( "indexPair" ), py::arg( "CoordinatesSpace" ) = CoordinatesSpace::Global );
+ class_.def( "getIntersectionArea", &MeshPairing::getIntersectionArea, R"(
+Get area of intersection for a given pair
+
+Arguments:
+ indexPair (integer): index of pair
+
+Returns:
+ real: area of intersection
+ )",
+ py::arg( "indexPair" ) );
+
+ // class_.def( "getIntersectionPoints", &MeshPairing::getIntersectionPoints, R"(
+ // Get coordinates of intersection points for a given pair in global space
+
+ // Arguments:
+ // indexPair (integer): index of pair
+
+ // Returns:
+ // list: intersection points
+ // )",
+ // py::arg( "indexPair" ) );
+ class_.def( "getQuadraturePoints", &MeshPairing::getQuadraturePoints, R"(
+Get coordinates of quadrature points for a given pair in global space
+
+Arguments:
+ indexPair (integer): index of pair
+
+Returns:
+ list: quadrature points
+ )",
+ py::arg( "indexPair" ) );
+ class_.def( "getVerbosity", &MeshPairing::getVerbosity, R"(
+Get level of verbosity
+
+Returns:
+ integer: level of verbosity
+ )" );
+ class_.def( "getMesh", &MeshPairing::getMesh, R"(
+Return the mesh
+
+Returns:
+ Mesh: mesh.
+ )" );
+ class_.def( "getMasterCellsFromNode", &MeshPairing::getMasterCellsFromNode, R"(
+Get the master cells associated with a node number
+
+Arguments:
+ int: node number
+
+Returns:
+ list: master cells associated
+ )",
+ py::arg( "node_number" ) );
+ class_.def( "getSlaveCellsFromNode", &MeshPairing::getSlaveCellsFromNode, R"(
+Get the slave cells associated with a node number
+
+Arguments:
+ int: node number
+
+Returns:
+ list: slave cells associated
+ )",
+ py::arg( "node_number" ) );
+ class_.def( "getMasterCellNeighbors", &MeshPairing::getMasterCellNeighbors, R"(
+Get the master cells in the neighbor of a given master cell number
+
+Arguments:
+ int: master cell number
+
+Returns:
+ list: master neighbors cells
+ )",
+ py::arg( "cell_number" ) );
+ class_.def( "setExcludedSlaveGroupOfNodes", &MeshPairing::setExcludedSlaveGroupOfNodes,
+ R"(
+Set excluded groups of nodes on slave side
+
+Arguments:
+ str: excluded groups' names
+ )",
+ py::arg( "groups" ) );
+ class_.def( "setExcludedSlaveGroupOfCells", &MeshPairing::setExcludedSlaveGroupOfCells, R"(
+Set excluded groups of cells on slave side
+
+Arguments:
+ str: excluded groups' names
+ )",
+ py::arg( "groups" ) );
+ class_.def( "getSlaveCellNeighbors", &MeshPairing::getSlaveCellNeighbors, R"(
+Get the slave cells in the neighbor of a given slave cell number
+
+Arguments:
+ int: slave cell number
+
+Returns:
+ list: slave neighbors cells
+ )",
+ py::arg( "cell_number" ) );
+ class_.def( "checkNormals", &MeshPairing::checkNormals, R"(
+Check orientation of normals
+
+Arguments:
+ ModelPtr: a pointer to the model
+
+Returns:
+ nothing
+ )",
+ py::arg( "model" ) );
+ class_.def( "setMethod", &MeshPairing::setMethod, R"(
+Set method of pairing
+
+Arguments:
+ method (PairingMethod): method ("OLD", "Fast", "Robust)
+ )",
+ py::arg( "method" ) );
+ py::enum_< PairingMethod >( mod, "PairingMethod", R"(
+Type of pairing: Fast, BrutForce and Legacy.)" )
+ .value( "Fast", PairingMethod::Fast )
+ .value( "Legacy", PairingMethod::Legacy )
+ .value( "BrutForce", PairingMethod::BrutForce )
+ .export_values();
+};
diff --git a/bibcxx/PythonBindings/MeshPairingInterface.h b/bibcxx/PythonBindings/MeshPairingInterface.h
new file mode 100644
index 00000000000..0a0d027accd
--- /dev/null
+++ b/bibcxx/PythonBindings/MeshPairingInterface.h
@@ -0,0 +1,34 @@
+#ifndef PAIRGEOMINTERFACE_H_
+#define PAIRGEOMINTERFACE_H_
+
+/**
+ * @file PairGeomInterface.h
+ * @brief Header of class PairGeomInterface
+ * @section LICENCE
+ * Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
+ *
+ * This file is part of Code_Aster.
+ *
+ * Code_Aster is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Code_Aster is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Code_Aster. If not, see .
+ */
+
+#include "astercxx.h"
+
+#include "aster_pybind.h"
+
+#include "Meshes/MeshPairing.h"
+
+void exportMeshPairingToPython( py::module_ &mod );
+
+#endif
diff --git a/bibcxx/PythonBindings/ResultInterface.cxx b/bibcxx/PythonBindings/ResultInterface.cxx
index a8a0b561bdc..45724dbf705 100644
--- a/bibcxx/PythonBindings/ResultInterface.cxx
+++ b/bibcxx/PythonBindings/ResultInterface.cxx
@@ -100,13 +100,14 @@ Returns
py::arg( "index" ) )
.def( "addEquationNumbering", &Result::addEquationNumbering )
.def( "setMaterialField",
- py::overload_cast< const MaterialFieldPtr & >( &Result::setMaterialField ), R"(
+ py::overload_cast< const MaterialFieldPtr &, bool >( &Result::setMaterialField ), R"(
Set material field on all indexs
Arguments:
mater (MaterialField): material field to set.
+ exists_ok (bool): If *True*, pass silently if a Model is already defined. *False* by default.
)",
- py::arg( "mater" ) )
+ py::arg( "mater" ), py::arg( "exists_ok" ) = false )
.def( "setMaterialField",
py::overload_cast< const MaterialFieldPtr &, ASTERINTEGER >(
&Result::setMaterialField ),
@@ -126,13 +127,14 @@ Set list of loads on the specified index
index (int): index to set
)",
py::arg( "load" ), py::arg( "index" ) )
- .def( "setModel", py::overload_cast< const ModelPtr & >( &Result::setModel ), R"(
+ .def( "setModel", py::overload_cast< const ModelPtr &, bool >( &Result::setModel ), R"(
Set model on all indexs
Arguments:
- model (Model): model to set.
+ model (Model): Model to be assigned.
+ exists_ok (bool): If *True*, pass silently if a Model is already defined. *False* by default.
)",
- py::arg( "model" ) )
+ py::arg( "model" ), py::arg( "exists_ok" ) = false )
.def( "setModel", py::overload_cast< const ModelPtr &, ASTERINTEGER >( &Result::setModel ),
R"(
Set model on the specified index
@@ -143,15 +145,16 @@ Set model on the specified index
)",
py::arg( "model" ), py::arg( "index" ) )
.def( "setElementaryCharacteristics",
- py::overload_cast< const ElementaryCharacteristicsPtr & >(
+ py::overload_cast< const ElementaryCharacteristicsPtr &, bool >(
&Result::setElementaryCharacteristics ),
R"(
Set elementary characterictics on all indexs
Arguments:
cara_elem (ElementaryCharacteristics): elementary characterictics to set.
+ exists_ok (bool): If *True*, pass silently if a Model is already defined. *False* by default.
)",
- py::arg( "cara_elem" ) )
+ py::arg( "cara_elem" ), py::arg( "exists_ok" ) = false )
.def( "setElementaryCharacteristics",
py::overload_cast< const ElementaryCharacteristicsPtr &, ASTERINTEGER >(
&Result::setElementaryCharacteristics ),
diff --git a/bibcxx/Results/Result.cxx b/bibcxx/Results/Result.cxx
index 7ec964efe2c..81dd2c54274 100644
--- a/bibcxx/Results/Result.cxx
+++ b/bibcxx/Results/Result.cxx
@@ -138,9 +138,15 @@ void Result::setMesh( const BaseMeshPtr &mesh ) {
};
void Result::setElementaryCharacteristics( const ElementaryCharacteristicsPtr &cara,
- ASTERINTEGER storageIndex ) {
+ ASTERINTEGER storageIndex, bool exists_ok ) {
if ( !cara )
raiseAsterError( "ValueError: ElementaryCharacteristics is empty" );
+ if ( _mapElemCara.count( storageIndex ) != 0 ) {
+ if ( exists_ok || _mapElemCara[storageIndex] == cara )
+ return;
+ raiseAsterError( "ValueError: ElementaryCharacteristics already assigned at index " +
+ std::to_string( storageIndex ) );
+ }
_mapElemCara[storageIndex] = cara;
std::string type( "CARAELEM" );
@@ -152,6 +158,12 @@ void Result::setElementaryCharacteristics( const ElementaryCharacteristicsPtr &c
void Result::setListOfLoads( const ListOfLoadsPtr &load, ASTERINTEGER storageIndex ) {
if ( !load )
raiseAsterError( "ValueError: Load is empty" );
+ if ( _mapLoads.count( storageIndex ) != 0 ) {
+ if ( _mapLoads[storageIndex] == load )
+ return;
+ raiseAsterError( "ValueError: Load already assigned at index " +
+ std::to_string( storageIndex ) );
+ }
_mapLoads[storageIndex] = load;
std::string type( "EXCIT" );
@@ -159,9 +171,16 @@ void Result::setListOfLoads( const ListOfLoadsPtr &load, ASTERINTEGER storageInd
CALLO_RSADPA_ZK24_WRAP( getName(), &storageIndex, load->getName(), type, cel );
};
-void Result::setMaterialField( const MaterialFieldPtr &mater, ASTERINTEGER storageIndex ) {
+void Result::setMaterialField( const MaterialFieldPtr &mater, ASTERINTEGER storageIndex,
+ bool exists_ok ) {
if ( !mater )
raiseAsterError( "ValueError: MaterialField is empty" );
+ if ( _mapMaterial.count( storageIndex ) != 0 ) {
+ if ( exists_ok || _mapMaterial[storageIndex] == mater )
+ return;
+ raiseAsterError( "ValueError: MaterialField already assigned at index " +
+ std::to_string( storageIndex ) );
+ }
_mapMaterial[storageIndex] = mater;
std::string type( "CHAMPMAT" );
@@ -170,9 +189,15 @@ void Result::setMaterialField( const MaterialFieldPtr &mater, ASTERINTEGER stora
setMesh( mater->getMesh() );
};
-void Result::setModel( const ModelPtr &model, ASTERINTEGER storageIndex ) {
+void Result::setModel( const ModelPtr &model, ASTERINTEGER storageIndex, bool exists_ok ) {
if ( !model )
raiseAsterError( "ValueError: Model is empty" );
+ if ( _mapModel.count( storageIndex ) != 0 ) {
+ if ( exists_ok || _mapModel[storageIndex] == model )
+ return;
+ raiseAsterError( "ValueError: Model already assigned at index " +
+ std::to_string( storageIndex ) );
+ }
_mapModel[storageIndex] = model;
std::string type( "MODELE" );
@@ -280,24 +305,25 @@ void Result::_listOfParameters() {
}
}
-void Result::setElementaryCharacteristics( const ElementaryCharacteristicsPtr &cara ) {
+void Result::setElementaryCharacteristics( const ElementaryCharacteristicsPtr &cara,
+ bool exists_ok ) {
auto allStorageIndexes = getIndexes();
for ( auto &storageIndex : allStorageIndexes ) {
- setElementaryCharacteristics( cara, storageIndex );
+ setElementaryCharacteristics( cara, storageIndex, exists_ok );
}
};
-void Result::setMaterialField( const MaterialFieldPtr &mater ) {
+void Result::setMaterialField( const MaterialFieldPtr &mater, bool exists_ok ) {
auto allStorageIndexes = getIndexes();
for ( auto &storageIndex : allStorageIndexes ) {
- setMaterialField( mater, storageIndex );
+ setMaterialField( mater, storageIndex, exists_ok );
}
};
-void Result::setModel( const ModelPtr &model ) {
+void Result::setModel( const ModelPtr &model, bool exists_ok ) {
auto allStorageIndexes = getIndexes();
for ( auto &storageIndex : allStorageIndexes ) {
- setModel( model, storageIndex );
+ setModel( model, storageIndex, exists_ok );
}
};
@@ -307,7 +333,9 @@ std::vector< ElementaryCharacteristicsPtr > Result::getAllElementaryCharacterist
ElementaryCharacteristicsPtr Result::getElementaryCharacteristics() const {
const auto cara = getAllElementaryCharacteristics();
- AS_ASSERT( cara.size() <= 1 );
+ if ( cara.size() > 1 ) {
+ UTMESS( "F", "RESULT2_8" );
+ }
if ( cara.size() == 1 )
return cara[0];
@@ -342,7 +370,9 @@ std::vector< MaterialFieldPtr > Result::getMaterialFields() const {
MaterialFieldPtr Result::getMaterialField() const {
const auto mate = getMaterialFields();
- AS_ASSERT( mate.size() <= 1 );
+ if ( mate.size() > 1 ) {
+ UTMESS( "F", "RESULT2_7" );
+ };
if ( mate.size() == 1 )
return mate[0];
@@ -387,7 +417,7 @@ std::vector< ModelPtr > Result::getModels() const { return unique( _mapModel );
ModelPtr Result::getModel() const {
if ( hasMultipleModel() ) {
- raiseAsterError( "Error: multiple models" );
+ UTMESS( "F", "RESULT2_6" );
}
const auto models = getModels();
diff --git a/bibcxx/Results/Result.h b/bibcxx/Results/Result.h
index 0037722a599..346d2decef6 100644
--- a/bibcxx/Results/Result.h
+++ b/bibcxx/Results/Result.h
@@ -214,7 +214,11 @@ class Result : public DataStructure, public ListOfTables {
* @param storageIndex
*/
void setElementaryCharacteristics( const ElementaryCharacteristicsPtr &elemCara,
- ASTERINTEGER storageIndex );
+ ASTERINTEGER storageIndex, bool exists_ok );
+ void setElementaryCharacteristics( const ElementaryCharacteristicsPtr &elemCara,
+ ASTERINTEGER storageIndex ) {
+ return setElementaryCharacteristics( elemCara, storageIndex, false );
+ };
/**
* @brief Add a existing EquationNumbering in _fieldBuilder
@@ -233,13 +237,20 @@ class Result : public DataStructure, public ListOfTables {
* @brief Add material definition
* @param storageIndex
*/
- void setMaterialField( const MaterialFieldPtr &mate, ASTERINTEGER storageIndex );
+ void setMaterialField( const MaterialFieldPtr &mate, ASTERINTEGER storageIndex,
+ bool exists_ok );
+ void setMaterialField( const MaterialFieldPtr &mate, ASTERINTEGER storageIndex ) {
+ return setMaterialField( mate, storageIndex, false );
+ }
/**
* @brief Add model
* @param storageIndex
*/
- void setModel( const ModelPtr &model, ASTERINTEGER storageIndex );
+ void setModel( const ModelPtr &model, ASTERINTEGER storageIndex, bool exists_ok );
+ void setModel( const ModelPtr &model, ASTERINTEGER storageIndex ) {
+ return setModel( model, storageIndex, false );
+ };
/**
* @brief Set model
@@ -282,19 +293,20 @@ class Result : public DataStructure, public ListOfTables {
* @brief Append a elementary characteristics on all index of Result
* @param ElementaryCharacteristicsPtr
*/
- void setElementaryCharacteristics( const ElementaryCharacteristicsPtr &cara );
+ void setElementaryCharacteristics( const ElementaryCharacteristicsPtr &cara,
+ bool exists_ok = false );
/**
* @brief Append a material on all index of Result
* @param MaterialFieldPtr
*/
- void setMaterialField( const MaterialFieldPtr &mate );
+ void setMaterialField( const MaterialFieldPtr &mate, bool exists_ok = false );
/**
* @brief Append a model on all index of Result
* @param ModelPtr
*/
- void setModel( const ModelPtr &model );
+ void setModel( const ModelPtr &model, bool exists_ok = false );
/**
* @brief Get list of loads at index
diff --git a/bibcxx/include/astercxx.h b/bibcxx/include/astercxx.h
index 6da21f26011..902b78c3ed4 100644
--- a/bibcxx/include/astercxx.h
+++ b/bibcxx/include/astercxx.h
@@ -50,6 +50,7 @@ using VectorComplex = std::vector< ASTERCOMPLEX >;
using VectorString = std::vector< std::string >;
using VectorOfVectorsLong = std::vector< VectorLong >;
+using VectorOfVectorsReal = std::vector< VectorReal >;
using SetInt = std::set< ASTERINTEGER4 >;
using SetLong = std::set< ASTERINTEGER >;
diff --git a/bibfor/cont_elem/getInterCont.F90 b/bibfor/cont_elem/getInterCont.F90
new file mode 100644
index 00000000000..00209861110
--- /dev/null
+++ b/bibfor/cont_elem/getInterCont.F90
@@ -0,0 +1,58 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+!
+subroutine getInterCont(nbPoinInte, poinInteSlav)
+!
+ implicit none
+!
+#include "asterf_types.h"
+#include "asterfort/assert.h"
+#include "asterfort/jevech.h"
+#include "asterfort/mesh_pairing_type.h"
+#include "jeveux.h"
+!
+ integer, intent(out) :: nbPoinInte
+ real(kind=8), intent(out) :: poinInteSlav(2, MAX_NB_INTE)
+!
+! --------------------------------------------------------------------------------------------------
+!
+! Contact - Quadrature
+!
+! Get intersection points
+!
+! --------------------------------------------------------------------------------------------------
+!
+! Out nbPoinInte : number of intersection points
+! Out poinInteSlav : coordinates of intersection points (in slave parametric space)
+!
+! --------------------------------------------------------------------------------------------------
+!
+ integer :: jcont, iPoinInte
+!
+! --------------------------------------------------------------------------------------------------
+!
+ call jevech('PCONFR', 'L', jcont)
+ nbPoinInte = int(zr(jcont-1+1))
+ ASSERT(nbPoinInte .le. MAX_NB_INTE)
+ poinInteSlav = 0.d0
+ do iPoinInte = 1, nbPoinInte
+ poinInteSlav(1, iPoinInte) = zr(jcont-1+1+iPoinInte)
+ poinInteSlav(2, iPoinInte) = zr(jcont-1+9+iPoinInte)
+ end do
+!
+end subroutine
diff --git a/bibfor/cont_elem/getQuadCont.F90 b/bibfor/cont_elem/getQuadCont.F90
index f8dd4e6751e..4dda7f65765 100644
--- a/bibfor/cont_elem/getQuadCont.F90
+++ b/bibfor/cont_elem/getQuadCont.F90
@@ -1,5 +1,5 @@
! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
! This file is part of code_aster.
!
! code_aster is free software: you can redistribute it and/or modify
@@ -16,29 +16,35 @@
! along with code_aster. If not, see .
! --------------------------------------------------------------------
!
-subroutine getQuadCont(elem_dime, l_axis, nb_node_slav, &
- elem_slav_code, elem_slav_coor, &
- elem_mast_code, &
- nb_qp, coor_qp, weight_qp)
+subroutine getQuadCont(elem_dime, &
+ elem_slav_code, elem_mast_code, &
+ nbPoinInte, poinInteSlav, &
+ nb_qp, coor_qp, &
+ l_axis_, nb_node_slav_, elem_slav_coor_, &
+ weight_qp_)
!
implicit none
!
#include "asterf_types.h"
#include "asterfort/assert.h"
-#include "asterfort/lcptga.h"
#include "asterfort/latrco.h"
-#include "asterfort/jevech.h"
+#include "asterfort/lcptga.h"
+#include "asterfort/mesh_pairing_type.h"
+#include "asterfort/mmdonf.h"
#include "asterfort/mmmjac.h"
#include "asterfort/mmnonf.h"
-#include "asterfort/mmdonf.h"
#include "jeveux.h"
!
- integer, intent(in) :: elem_dime, nb_node_slav
- aster_logical, intent(in) :: l_axis
+ integer, intent(in) :: elem_dime
character(len=8), intent(in) :: elem_slav_code, elem_mast_code
- real(kind=8), intent(in) :: elem_slav_coor(3, 9)
- real(kind=8), intent(out) :: coor_qp(2, 48), weight_qp(48)
+ integer, intent(in) :: nbPoinInte
+ real(kind=8), intent(in) :: poinInteSlav(2, MAX_NB_INTE)
+ real(kind=8), intent(out) :: coor_qp(2, MAX_NB_QUAD)
integer, intent(out) :: nb_qp
+ integer, optional, intent(in) :: nb_node_slav_
+ real(kind=8), optional, intent(in) :: elem_slav_coor_(3, 9)
+ aster_logical, optional, intent(in) :: l_axis_
+ real(kind=8), optional, intent(out) :: weight_qp_(MAX_NB_QUAD)
!
! --------------------------------------------------------------------------------------------------
!
@@ -48,20 +54,22 @@ subroutine getQuadCont(elem_dime, l_axis, nb_node_slav, &
!
! --------------------------------------------------------------------------------------------------
!
-! In elem_dime : dimension of elements
+! In modelDime : dimension of model
! In elem_slav_code : code element for slave side from contact element
! In elem_slav_coor : coordinates from slave side of contact element
-! Out nb_qp : number of quadrature points
-! Out coor_qp : coordinates of quadrature points (parametric slave space)
-! Out weight_qp : weight of quadrature points
+! In nbPoinInte : number of intersection points
+! In poinInteSlav : coordinates of intersection points (in slave parametric space)
+! Out nb_qp : number of quadrature points
+! Out coor_qp : coordinates of quadrature points (parametric slave space)
+! Out weight_qp : weight of quadrature points
!
! --------------------------------------------------------------------------------------------------
!
aster_logical :: l_slav_line, l_mast_line
- integer :: i_node, i_dime, i_tria, i_gauss, jcont
- integer :: nb_tria, nb_poin_inte, nb_gauss
- real(kind=8) :: tria_coot_sl(2, 3), tria_coor_sl(16), poin_inte_sl(16)
- real(kind=8) :: gauss_weight_sl(12), gauss_coor_sl(2, 12)
+ integer :: iTria, iGauss
+ integer :: nbTria, nbGauss
+ real(kind=8) :: triaCoorSlav(2, 3)
+ real(kind=8) :: gausWeightSlav(12), gausCoorSlav(2, 12)
real(kind=8) :: shape_func(9), shape_dfunc(2, 9), jacobian_sl
character(len=8) :: elga_fami
!
@@ -69,25 +77,19 @@ subroutine getQuadCont(elem_dime, l_axis, nb_node_slav, &
!
nb_qp = 0
coor_qp = 0
- weight_qp = 0
-!
-! - Get intersection point
-!
- call jevech('PCONFR', 'L', jcont)
- nb_poin_inte = int(zr(jcont-1+1))
- poin_inte_sl = zr(jcont-1+2:jcont-1+17)
-!
+ if (present(weight_qp_)) then
+ weight_qp_ = 0.d0
+ end if
l_slav_line = elem_slav_code == "SE2" .or. elem_slav_code == "TR3" .or. elem_slav_code == "QU4"
l_mast_line = elem_mast_code == "SE2" .or. elem_mast_code == "TR3" .or. elem_mast_code == "QU4"
-!
+
! - Triangulation of convex polygon defined by intersection points
if (elem_dime .eq. 3) then
- if (nb_poin_inte == 3) then
- nb_tria = 1
+ if (nbPoinInte == 3) then
+ nbTria = 1
else
- nb_tria = nb_poin_inte
+ nbTria = nbPoinInte
end if
-!
if (l_slav_line .and. l_mast_line) then
! order 3 by triangle
elga_fami = 'FPG4'
@@ -96,7 +98,7 @@ subroutine getQuadCont(elem_dime, l_axis, nb_node_slav, &
elga_fami = 'FPG7'
end if
elseif (elem_dime .eq. 2) then
- nb_tria = 1
+ nbTria = 1
if (l_slav_line .and. l_mast_line) then
! order 5
elga_fami = 'FPG3'
@@ -107,56 +109,47 @@ subroutine getQuadCont(elem_dime, l_axis, nb_node_slav, &
else
ASSERT(ASTER_FALSE)
end if
+
! - Loop on triangles
- do i_tria = 1, nb_tria
+ do iTria = 1, nbTria
! ----- Coordinates of current triangle (slave)
- tria_coor_sl(:) = 0.d0
+ triaCoorSlav = 0.d0
if (elem_dime .eq. 3) then
- call latrco(i_tria, nb_poin_inte, poin_inte_sl, tria_coor_sl)
+ call latrco(iTria, nbPoinInte, poinInteSlav, triaCoorSlav)
elseif (elem_dime .eq. 2) then
- tria_coor_sl(1:16) = poin_inte_sl(1:16)
- end if
-! ----- Change shape of vector (slave)
- tria_coot_sl(1:2, 1:3) = 0.d0
- if (elem_dime .eq. 3) then
- do i_node = 1, 3
- do i_dime = 1, (elem_dime-1)
- tria_coot_sl(i_dime, i_node) = &
- tria_coor_sl((i_node-1)*(elem_dime-1)+i_dime)
- end do
- end do
- else
- tria_coot_sl(1, 1) = tria_coor_sl(1)
- tria_coot_sl(2, 1) = 0.d0
- tria_coot_sl(1, 2) = tria_coor_sl(2)
- tria_coot_sl(2, 2) = 0.d0
+ ASSERT(nbPoinInte .eq. 2)
+ triaCoorSlav(1:2, 1:2) = poinInteSlav(1:2, 1:2)
end if
+
! ----- Get integration points for slave element
- call lcptga(elem_dime, tria_coot_sl, elga_fami, &
- nb_gauss, gauss_coor_sl, gauss_weight_sl)
+ call lcptga(elem_dime, triaCoorSlav, elga_fami, &
+ nbGauss, gausCoorSlav, gausWeightSlav)
+
! ----- Loop on integration points
- do i_gauss = 1, nb_gauss
+ do iGauss = 1, nbGauss
nb_qp = nb_qp+1
- ASSERT(nb_qp <= 48)
+ ASSERT(nb_qp <= MAX_NB_QUAD)
+
! --------- Get current integration point (slave)
- do i_dime = 1, elem_dime-1
- coor_qp(i_dime, nb_qp) = gauss_coor_sl(i_dime, i_gauss)
- end do
-!
-! - Get shape functions and first derivative only (for perf)
-!
- call mmnonf(elem_dime, nb_node_slav, elem_slav_code, &
- gauss_coor_sl(1, i_gauss), gauss_coor_sl(2, i_gauss), &
- shape_func)
- call mmdonf(elem_dime, nb_node_slav, elem_slav_code, &
- gauss_coor_sl(1, i_gauss), gauss_coor_sl(2, i_gauss), &
- shape_dfunc)
-! --------- Compute jacobian
- call mmmjac(l_axis, nb_node_slav, elem_dime, &
- elem_slav_code, elem_slav_coor, &
- shape_func, shape_dfunc, jacobian_sl)
+ coor_qp(1:2, nb_qp) = gausCoorSlav(1:2, iGauss)
+ ! WRITE (6, *) "coor_qp: ", coor_qp(:, nb_qp)
+
+ if (present(weight_qp_)) then
+! ------------- Get shape functions and first derivative only (for perf)
+ call mmnonf(elem_dime, nb_node_slav_, elem_slav_code, &
+ gausCoorSlav(1, iGauss), gausCoorSlav(2, iGauss), &
+ shape_func)
+ call mmdonf(elem_dime, nb_node_slav_, elem_slav_code, &
+ gausCoorSlav(1, iGauss), gausCoorSlav(2, iGauss), &
+ shape_dfunc)
+
+! ------------- Compute jacobian
+ call mmmjac(l_axis_, nb_node_slav_, elem_dime, &
+ elem_slav_code, elem_slav_coor_, &
+ shape_func, shape_dfunc, jacobian_sl)
- weight_qp(nb_qp) = jacobian_sl*gauss_weight_sl(i_gauss)
+ weight_qp_(nb_qp) = jacobian_sl*gausWeightSlav(iGauss)
+ end if
end do
end do
!
diff --git a/bibfor/cont_elem/laMatr.F90 b/bibfor/cont_elem/laMatr.F90
index 23ca4a88bd9..2a6975d735b 100644
--- a/bibfor/cont_elem/laMatr.F90
+++ b/bibfor/cont_elem/laMatr.F90
@@ -18,13 +18,14 @@
!
subroutine laMatr(parameters, geom, matr_cont, matr_fric)
!
- use contact_type
use contact_module
+ use contact_type
!
implicit none
!
#include "asterf_types.h"
#include "asterfort/assert.h"
+#include "asterfort/getInterCont.h"
#include "asterfort/getQuadCont.h"
#include "asterfort/laElemCont.h"
#include "blas/dgemm.h"
@@ -54,12 +55,12 @@ subroutine laMatr(parameters, geom, matr_cont, matr_fric)
! In elem_slav_code : code element for slave side from contact element
! In nb_node_mast : number of nodes of for master side from contact element
! In elem_mast_code : code element for master side from contact element
-! IO matr_cont : matrix (only upper part)
+! IO matr_cont : matrix (only upper part)
!
! --------------------------------------------------------------------------------------------------
!
aster_logical :: l_cont_qp, l_fric_qp
- integer :: i_qp, nb_qp
+ integer :: i_qp, nb_qp
real(kind=8) :: weight_sl_qp, coeff, hF
real(kind=8) :: coor_qp_sl(2)
real(kind=8) :: coor_qp(2, 48), weight_qp(48)
@@ -67,6 +68,8 @@ subroutine laMatr(parameters, geom, matr_cont, matr_fric)
real(kind=8) :: lagr_f(2), vT(2), gamma_f, projBsVal(2)
real(kind=8) :: dGap(MAX_LAGA_DOFS), mu_c(MAX_LAGA_DOFS), d2Gap(MAX_LAGA_DOFS, MAX_LAGA_DOFS)
real(kind=8) :: mu_f(MAX_LAGA_DOFS, 2)
+ integer :: nbPoinInte
+ real(kind=8) :: poinInteSlav(2, MAX_NB_INTE)
blas_int :: b_k, b_lda, b_ldb, b_ldc, b_m, b_n
blas_int :: b_incx, b_incy
!
@@ -74,9 +77,8 @@ subroutine laMatr(parameters, geom, matr_cont, matr_fric)
!
matr_cont = 0.d0
matr_fric = 0.d0
-!
+
! - Slave node is not paired -> Special treatment
-!
if (geom%elem_slav_code == "PO1") then
if (geom%elem_mast_code == "LAGR") then
matr_cont(geom%elem_dime+1, geom%elem_dime+1) = 1.d0
@@ -94,39 +96,39 @@ subroutine laMatr(parameters, geom, matr_cont, matr_fric)
!
go to 999
end if
-!
+
+! - Get intersection points
+ call getInterCont(nbPoinInte, poinInteSlav)
+
! - Get quadrature (slave side)
-!
- call getQuadCont(geom%elem_dime, geom%l_axis, geom%nb_node_slav, geom%elem_slav_code, &
- geom%coor_slav_init, geom%elem_mast_code, nb_qp, coor_qp, weight_qp)
-!
+ call getQuadCont(geom%elem_dime, &
+ geom%elem_slav_code, geom%elem_mast_code, &
+ nbPoinInte, poinInteSlav, &
+ nb_qp, coor_qp, &
+ geom%l_axis, geom%nb_node_slav, geom%coor_slav_init, &
+ weight_qp)
+
! - Diameter of slave side
-!
hF = diameter(geom%nb_node_slav, geom%coor_slav_init)
-!
+
! - Loop on quadrature points
-!
do i_qp = 1, nb_qp
!
! ----- Get current quadrature point (slave side)
!
coor_qp_sl(1:2) = coor_qp(1:2, i_qp)
weight_sl_qp = weight_qp(i_qp)
-!
+
! ----- Compute contact quantities
-!
- call laElemCont(parameters, geom, coor_qp_sl, hF, lagr_c, &
- gap, gamma_c, projRmVal, l_cont_qp, lagr_f, &
- vT, gamma_f, projBsVal, l_fric_qp, dGap=dGap, &
- d2Gap=d2Gap, mu_c=mu_c, mu_f=mu_f)
-!
+ call laElemCont(parameters, geom, coor_qp_sl, hF, &
+ lagr_c, gap, gamma_c, projRmVal, l_cont_qp, &
+ lagr_f, vT, gamma_f, projBsVal, l_fric_qp, &
+ dGap=dGap, d2Gap=d2Gap, mu_c=mu_c, mu_f=mu_f)
+
! ------ CONTACT PART (always computed)
-!
if (l_cont_qp) then
-!
! ------ Compute displacement / displacement (slave and master side)
! term: (gamma_c*H*D(gap(u))[v], D(gap(u))[du])
-!
coeff = weight_sl_qp*gamma_c
b_lda = to_blas_int(MAX_LAGA_DOFS)
b_m = to_blas_int(geom%nb_dofs)
@@ -138,15 +140,13 @@ subroutine laMatr(parameters, geom, matr_cont, matr_fric)
!
! ------ Compute displacement / displacement (slave and master side)
! term: (H*[lagr_c + gamma_c * gap(u)]_R-, D2(gap(u))[v, du])
-!
coeff = weight_sl_qp*projRmVal
- matr_cont(1:geom%nb_dofs, 1:geom%nb_dofs) = matr_cont(1:geom%nb_dofs, 1:geom%nb_dofs)&
- &+coeff*d2Gap(1:geom%nb_dofs, 1:geom%nb_d&
- &ofs)
-!
+ matr_cont(1:geom%nb_dofs, 1:geom%nb_dofs) = &
+ matr_cont(1:geom%nb_dofs, 1:geom%nb_dofs)+ &
+ coeff*d2Gap(1:geom%nb_dofs, 1:geom%nb_dofs)
+
! ------ Compute displacement / Lagrange and Lagrange / displacement
! term: (H * D(gap(u))[v], dlagr_c) + (H * mu_c, D(gap(u))[du])
-!
coeff = weight_sl_qp
b_lda = to_blas_int(MAX_LAGA_DOFS)
b_m = to_blas_int(geom%nb_dofs)
@@ -163,10 +163,9 @@ subroutine laMatr(parameters, geom, matr_cont, matr_fric)
call dger(b_m, b_n, coeff, mu_c, b_incx, &
dGap, b_incy, matr_cont, b_lda)
else
-!
+
! ------ Compute Lagrange / Lagrange (slave side)
! term: ((H-1) / gamma_c * mu_c, dlagr_c) = (- mu_c / gamma_c, dlagr_c) since H = 0
-!
coeff = -weight_sl_qp/gamma_c
b_lda = to_blas_int(MAX_LAGA_DOFS)
b_m = to_blas_int(geom%nb_dofs)
@@ -177,17 +176,15 @@ subroutine laMatr(parameters, geom, matr_cont, matr_fric)
mu_c, b_incy, matr_cont, b_lda)
!
end if
-!
+
! ------ FRICTION PART (computed only if friction)
-!
if (parameters%l_fric) then
if (l_fric_qp) then
ASSERT(ASTER_FALSE)
else
-!
+
! ------ Compute Lagrange / Lagrange (slave side)
! term: (-1/ gamma_f * mu_f, dlagr_f) - Without friction
-!
coeff = -weight_sl_qp/gamma_f
b_ldc = to_blas_int(MAX_LAGA_DOFS)
b_ldb = to_blas_int(MAX_LAGA_DOFS)
diff --git a/bibfor/cont_elem/laVect.F90 b/bibfor/cont_elem/laVect.F90
index abb3ff331e9..257f4422865 100644
--- a/bibfor/cont_elem/laVect.F90
+++ b/bibfor/cont_elem/laVect.F90
@@ -25,6 +25,7 @@ subroutine laVect(parameters, geom, vect_cont, vect_fric)
!
#include "asterf_types.h"
#include "asterfort/assert.h"
+#include "asterfort/getInterCont.h"
#include "asterfort/getQuadCont.h"
#include "asterfort/laElemCont.h"
#include "blas/daxpy.h"
@@ -59,7 +60,7 @@ subroutine laVect(parameters, geom, vect_cont, vect_fric)
! --------------------------------------------------------------------------------------------------
!
aster_logical :: l_cont_qp, l_fric_qp
- integer :: i_qp, nb_qp
+ integer :: i_qp, nb_qp
real(kind=8) :: weight_sl_qp, coeff, hF
real(kind=8) :: coor_qp_sl(2)
real(kind=8) :: coor_qp(2, 48), weight_qp(48)
@@ -67,6 +68,8 @@ subroutine laVect(parameters, geom, vect_cont, vect_fric)
real(kind=8) :: lagr_f(2), vT(2), gamma_f, projBsVal(2), term_f(2)
real(kind=8) :: dGap(MAX_LAGA_DOFS), mu_c(MAX_LAGA_DOFS)
real(kind=8) :: mu_f(MAX_LAGA_DOFS, 2), jump_t(MAX_LAGA_DOFS, 3)
+ integer :: nbPoinInte
+ real(kind=8) :: poinInteSlav(2, MAX_NB_INTE)
blas_int :: b_incx, b_incy, b_n
blas_int :: b_lda, b_m
!
@@ -94,11 +97,17 @@ subroutine laVect(parameters, geom, vect_cont, vect_fric)
!
go to 999
end if
-!
+
+! - Get intersection points
+ call getInterCont(nbPoinInte, poinInteSlav)
+
! - Get quadrature (slave side)
-!
- call getQuadCont(geom%elem_dime, geom%l_axis, geom%nb_node_slav, geom%elem_slav_code, &
- geom%coor_slav_init, geom%elem_mast_code, nb_qp, coor_qp, weight_qp)
+ call getQuadCont(geom%elem_dime, &
+ geom%elem_slav_code, geom%elem_mast_code, &
+ nbPoinInte, poinInteSlav, &
+ nb_qp, coor_qp, &
+ geom%l_axis, geom%nb_node_slav, geom%coor_slav_init, &
+ weight_qp)
!
! - Diameter of slave side
!
@@ -115,10 +124,10 @@ subroutine laVect(parameters, geom, vect_cont, vect_fric)
!
! ----- Compute contact quantities
!
- call laElemCont(parameters, geom, coor_qp_sl, hF, lagr_c, &
- gap, gamma_c, projRmVal, l_cont_qp, lagr_f, &
- vT, gamma_f, projBsVal, l_fric_qp, dGap=dGap, &
- mu_c=mu_c, mu_f=mu_f, jump_t=jump_t)
+ call laElemCont(parameters, geom, coor_qp_sl, hF, &
+ lagr_c, gap, gamma_c, projRmVal, l_cont_qp, &
+ lagr_f, vT, gamma_f, projBsVal, l_fric_qp, &
+ dGap=dGap, mu_c=mu_c, mu_f=mu_f, jump_t=jump_t)
!
! ------ CONTACT PART (always computed)
!
diff --git a/bibfor/cont_elem/latrco.F90 b/bibfor/cont_elem/latrco.F90
index 039a92136e3..9c8ce0d71ab 100644
--- a/bibfor/cont_elem/latrco.F90
+++ b/bibfor/cont_elem/latrco.F90
@@ -1,5 +1,5 @@
! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
! This file is part of code_aster.
!
! code_aster is free software: you can redistribute it and/or modify
@@ -15,18 +15,18 @@
! You should have received a copy of the GNU General Public License
! along with code_aster. If not, see .
! --------------------------------------------------------------------
-
-subroutine latrco(i_tria, nb_poin_inte, poin_inte, tria_coor)
+!
+subroutine latrco(iTria, nbPoinInte, poinInte, triaCoorPara)
!
implicit none
!
#include "asterfort/assert.h"
+#include "asterfort/mesh_pairing_type.h"
!
-!
- integer, intent(in) :: i_tria
- integer, intent(in) :: nb_poin_inte
- real(kind=8), intent(in) :: poin_inte(2, 8)
- real(kind=8), intent(out) :: tria_coor(2, 3)
+ integer, intent(in) :: iTria
+ integer, intent(in) :: nbPoinInte
+ real(kind=8), intent(in) :: poinInte(2, MAX_NB_INTE)
+ real(kind=8), intent(out) :: triaCoorPara(2, 3)
!
! --------------------------------------------------------------------------------------------------
!
@@ -36,34 +36,34 @@ subroutine latrco(i_tria, nb_poin_inte, poin_inte, tria_coor)
!
! --------------------------------------------------------------------------------------------------
!
-! In i_tria : index of current triangle
-! In tria_node : list of triangles (defined by index of intersection points)
-! In poin_inte : list (sorted) of intersection points
-! Out tria_coor : coordinates of current triangle
+! In iTria : index of current triangle
+! In nbPoinInte : number of intersection points
+! In poinInte : coordinates of intersection points (in cell parametric space)
+! Out triaCoorPara : coordinates of current triangle (in cell parametric space)
!
! --------------------------------------------------------------------------------------------------
!
- integer :: i_node, i_node1, i_node2
+ integer :: iPoinInte, iPoinInte1, iPoinInte2
real(kind=8) :: barycenter(2)
!
! --------------------------------------------------------------------------------------------------
!
- if (nb_poin_inte == 3) then
- tria_coor(1:2, 1:3) = poin_inte(1:2, 1:3)
+ if (nbPoinInte == 3) then
+ triaCoorPara(1:2, 1:3) = poinInte(1:2, 1:3)
else
barycenter = 0.d0
- do i_node = 1, nb_poin_inte
- barycenter(1:2) = barycenter(1:2)+poin_inte(1:2, i_node)
+ do iPoinInte = 1, nbPoinInte
+ barycenter(1:2) = barycenter(1:2)+poinInte(1:2, iPoinInte)
end do
- barycenter = barycenter/real(nb_poin_inte, kind=8)
-!
- i_node1 = i_tria
- i_node2 = i_tria+1
- if (i_tria == nb_poin_inte) i_node2 = 1
-
- tria_coor(1:2, 1) = poin_inte(1:2, i_node1)
- tria_coor(1:2, 2) = poin_inte(1:2, i_node2)
- tria_coor(1:2, 3) = barycenter
+ barycenter = barycenter/real(nbPoinInte, kind=8)
+ iPoinInte1 = iTria
+ iPoinInte2 = iTria+1
+ if (iTria == nbPoinInte) then
+ iPoinInte2 = 1
+ end if
+ triaCoorPara(1:2, 1) = poinInte(1:2, iPoinInte1)
+ triaCoorPara(1:2, 2) = poinInte(1:2, iPoinInte2)
+ triaCoorPara(1:2, 3) = barycenter
end if
!
end subroutine
diff --git a/bibfor/cont_elem/niMatr.F90 b/bibfor/cont_elem/niMatr.F90
index ed1e8353857..7b7cfa79f2e 100644
--- a/bibfor/cont_elem/niMatr.F90
+++ b/bibfor/cont_elem/niMatr.F90
@@ -18,14 +18,15 @@
!
subroutine niMatr(parameters, geom, matr_cont, matr_fric)
!
+ use contact_module
use contact_nitsche_module
use contact_type
- use contact_module
!
implicit none
!
#include "asterf_types.h"
#include "asterfort/assert.h"
+#include "asterfort/getInterCont.h"
#include "asterfort/getQuadCont.h"
#include "asterfort/niElemCont.h"
#include "blas/dgemm.h"
@@ -51,7 +52,7 @@ subroutine niMatr(parameters, geom, matr_cont, matr_fric)
!
type(ContactNitsche) :: nits
aster_logical :: l_cont_qp, l_fric_qp
- integer :: i_qp, nb_qp, total_dofs, face_dofs, slav_dofs
+ integer :: i_qp, nb_qp, total_dofs, face_dofs, slav_dofs
real(kind=8) :: weight_sl_qp, coeff, hF
real(kind=8) :: coor_qp_sl(2)
real(kind=8) :: coor_qp(2, 48), weight_qp(48)
@@ -61,6 +62,8 @@ subroutine niMatr(parameters, geom, matr_cont, matr_fric)
real(kind=8) :: dStress_nn(MAX_NITS_DOFS), dGapRenum(MAX_NITS_DOFS)
real(kind=8) :: matr_tmp(MAX_LAGA_DOFS, MAX_LAGA_DOFS)
integer :: dofsMap(54)
+ integer :: nbPoinInte
+ real(kind=8) :: poinInteSlav(2, MAX_NB_INTE)
blas_int :: b_incx, b_incy, b_lda, b_m, b_n
!
! --------------------------------------------------------------------------------------------------
@@ -70,17 +73,22 @@ subroutine niMatr(parameters, geom, matr_cont, matr_fric)
dGapRenum = 0.d0
!
! - Mapping of dofs
-!
dofsMap = dofsMapping(geom)
-!
+
+! - Get intersection points
+ call getInterCont(nbPoinInte, poinInteSlav)
+
! - Get quadrature (slave side)
-!
- call getQuadCont(geom%elem_dime, geom%l_axis, geom%nb_node_slav, geom%elem_slav_code, &
- geom%coor_slav_init, geom%elem_mast_code, nb_qp, coor_qp, weight_qp)
-!
+ call getQuadCont(geom%elem_dime, &
+ geom%elem_slav_code, geom%elem_mast_code, &
+ nbPoinInte, poinInteSlav, &
+ nb_qp, coor_qp, &
+ geom%l_axis, geom%nb_node_slav, geom%coor_slav_init, &
+ weight_qp)
+
! - Diameter of slave side
-!
hF = diameter(geom%nb_node_slav, geom%coor_slav_init)
+
!
call nbDofsNitsche(geom, total_dofs, face_dofs, slav_dofs)
!
@@ -163,7 +171,7 @@ subroutine niMatr(parameters, geom, matr_cont, matr_fric)
call dger(b_m, b_n, coeff, dStress_nn, b_incx, &
dGapRenum, b_incy, matr_cont, b_lda)
end if
-!
+
else
if (parameters%vari_cont .ne. CONT_VARI_RAPI) then
!
diff --git a/bibfor/cont_elem/niVect.F90 b/bibfor/cont_elem/niVect.F90
index 1bf6a6b6db1..0abe3a02cef 100644
--- a/bibfor/cont_elem/niVect.F90
+++ b/bibfor/cont_elem/niVect.F90
@@ -19,13 +19,14 @@
subroutine niVect(parameters, geom, vect_cont, vect_fric)
!
use contact_module
- use contact_type
use contact_nitsche_module
+ use contact_type
!
implicit none
!
#include "asterf_types.h"
#include "asterfort/assert.h"
+#include "asterfort/getInterCont.h"
#include "asterfort/getQuadCont.h"
#include "asterfort/niElemCont.h"
#include "blas/daxpy.h"
@@ -51,7 +52,7 @@ subroutine niVect(parameters, geom, vect_cont, vect_fric)
!
type(ContactNitsche) :: nits
aster_logical :: l_cont_qp, l_fric_qp
- integer :: i_qp, nb_qp, total_dofs, face_dofs, slav_dofs
+ integer :: i_qp, nb_qp, total_dofs, face_dofs, slav_dofs
real(kind=8) :: weight_sl_qp, coeff, hF
real(kind=8) :: coor_qp_sl(2)
real(kind=8) :: coor_qp(2, 48), weight_qp(48)
@@ -60,6 +61,8 @@ subroutine niVect(parameters, geom, vect_cont, vect_fric)
real(kind=8) :: dGap(MAX_LAGA_DOFS), dStress_nn(MAX_NITS_DOFS)
real(kind=8) :: jump_t(MAX_LAGA_DOFS, 3)
integer :: dofsMap(54)
+ integer :: nbPoinInte
+ real(kind=8) :: poinInteSlav(2, MAX_NB_INTE)
blas_int :: b_incx, b_incy, b_n
blas_int :: b_lda, b_m
!
@@ -67,18 +70,22 @@ subroutine niVect(parameters, geom, vect_cont, vect_fric)
!
vect_cont = 0.d0
vect_fric = 0.d0
-!
+
! - Mapping of dofs
-!
dofsMap = dofsMapping(geom)
-!
+
+! - Get intersection points
+ call getInterCont(nbPoinInte, poinInteSlav)
+
! - Get quadrature (slave side)
-!
- call getQuadCont(geom%elem_dime, geom%l_axis, geom%nb_node_slav, geom%elem_slav_code, &
- geom%coor_slav_init, geom%elem_mast_code, nb_qp, coor_qp, weight_qp)
-!
+ call getQuadCont(geom%elem_dime, &
+ geom%elem_slav_code, geom%elem_mast_code, &
+ nbPoinInte, poinInteSlav, &
+ nb_qp, coor_qp, &
+ geom%l_axis, geom%nb_node_slav, geom%coor_slav_init, &
+ weight_qp)
+
! - Diameter of slave side
-!
hF = diameter(geom%nb_node_slav, geom%coor_slav_init)
!
call nbDofsNitsche(geom, total_dofs, face_dofs, slav_dofs)
diff --git a/bibfor/cont_pair/aplcpgn.F90 b/bibfor/cont_pair/aplcpgn.F90
index b60ebbe6d80..56fe690bda9 100644
--- a/bibfor/cont_pair/aplcpgn.F90
+++ b/bibfor/cont_pair/aplcpgn.F90
@@ -1,5 +1,5 @@
! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
! This file is part of code_aster.
!
! code_aster is free software: you can redistribute it and/or modify
@@ -15,15 +15,19 @@
! You should have received a copy of the GNU General Public License
! along with code_aster. If not, see .
! --------------------------------------------------------------------
-
!
-subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
+subroutine aplcpgn(mesh, newgeo, &
+ mastConxInvName, mastNeighName, slavNeighName, &
+ pair_tole, dist_ratio, &
nb_elem_mast, list_elem_mast, nb_elem_slav, list_elem_slav, list_node_mast, &
- nb_node_mast, nb_pair_zone, list_pair_zone, list_nbptit_zone, list_ptitsl_zone)
+ nb_node_mast, meshPairing)
+!
+ use mesh_type
+ use mesh_cell_module
+ use MeshPairing_module
!
implicit none
!
-!#include "asterfort/ap_infast.h"
#include "asterc/r8nnem.h"
#include "asterf_types.h"
#include "asterfort/ap_infast_n.h"
@@ -51,11 +55,11 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
#include "asterfort/wkvect.h"
#include "jeveux.h"
#include "Contact_type.h"
-!
!
character(len=8), intent(in) :: mesh
character(len=19), intent(in) :: newgeo
- character(len=19), intent(in) :: zone
+ character(len=24), intent(in) :: mastConxInvName
+ character(len=24), intent(in) :: mastNeighName, slavNeighName
real(kind=8), intent(in) :: pair_tole, dist_ratio
integer, intent(in) :: nb_elem_slav
integer, intent(in) :: nb_elem_mast
@@ -63,10 +67,7 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
integer, intent(in) :: list_elem_mast(nb_elem_mast)
integer, intent(in) :: list_elem_slav(nb_elem_slav)
integer, intent(in) :: list_node_mast(nb_node_mast)
- integer, intent(out) :: nb_pair_zone
- character(len=19), intent(in) :: list_pair_zone, list_nbptit_zone
- character(len=19), intent(in) :: list_ptitsl_zone
- character(len=24), intent(in) :: pair_method
+ type(MESH_PAIRING), intent(inout) :: meshPairing
!
! --------------------------------------------------------------------------------------------------
!
@@ -74,11 +75,13 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
!
! Pairing by PANG method
!
+! NO OUTPUT (only for verbose debug)
+!
! --------------------------------------------------------------------------------------------------
!
! In mesh : name of mesh
! In newgeo : name of field for geometry update from initial coordinates of nodes
-! In zone : name of contactzone sd
+! In zone : name of contact zone sd
! In pair_tole : tolerance for pairing
! In nb_elem_mast : number of master elements on current zone
! In nb_elem_slav : number of slave elements on current zone
@@ -106,13 +109,12 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
real(kind=8) :: poin_inte_ma(SIZE_MAX_INTE_SL)
character(len=8) :: elem_slav_name, elem_name
integer :: nb_slav_start, nb_find_mast, nb_mast_start
- integer :: elem_start, elem_nume, jtab
+ integer :: elem_start, elem_nume
integer :: slav_indx_mini, mast_indx_mini, slav_indx_maxi, mast_indx_maxi
integer :: elem_neigh_indx, mast_find_indx, elem_slav_neigh, elem_mast_neigh
aster_logical :: l_recup, debug, pair_exist
integer, pointer :: mast_find_flag(:) => null()
integer, pointer :: elem_slav_flag(:) => null()
- character(len=24) :: sdappa_slne, sdappa_mane
integer, pointer :: v_sdappa_slne(:) => null()
integer, pointer :: v_sdappa_mane(:) => null()
integer :: list_slav_master(4)
@@ -132,8 +134,6 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
integer, pointer :: elem_mast_start(:) => null()
!
! --------------------------------------------------------------------------------------------------
-!
-! --------------------------------------------------------------------------------------------------
!
call jemarq()
!
@@ -173,27 +173,26 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
AS_ALLOCATE(vi=elem_slav_start, size=nb_elem_slav)
AS_ALLOCATE(vi=elem_mast_start, size=nb_elem_slav)
list_find_mast = 0
-!
+
! - Object for neighbours (inverse connectivity)
-!
- sdappa_mane = zone(1:8)//'.MN'
- sdappa_slne = zone(1:8)//'.SN'
- call jeveuo(sdappa_mane, 'L', vi=v_sdappa_mane)
- call jeveuo(sdappa_slne, 'L', vi=v_sdappa_slne)
-!
+ call jeveuo(mastNeighName, 'L', vi=v_sdappa_mane)
+ call jeveuo(slavNeighName, 'L', vi=v_sdappa_slne)
+
! - while loop on the existence of a pair slave-master
-!
do while (pair_exist)
- if (pair_method == "RAPIDE") then
- ! - Search by computing the minimum distance between the barycenters
- call ap_infast_n(mesh, newgeo, pair_tole, dist_ratio, nb_elem_mast, &
- list_elem_mast, nb_elem_slav, list_elem_slav, elem_slav_flag, &
- nb_mast_start, elem_mast_start, nb_slav_start, elem_slav_start, &
- zone, list_node_mast, nb_node_mast)
- elseif (pair_method == "ROBUSTE") then
- call apprin_n(mesh, newgeo, pair_tole, dist_ratio, nb_elem_mast, &
- list_elem_mast, nb_elem_slav, list_elem_slav, elem_slav_flag, &
- nb_mast_start, elem_mast_start, nb_slav_start, elem_slav_start)
+ if (debug) then
+ WRITE (6, *) "Get cells for starting search"
+ WRITE (6, *) "============================="
+ end if
+
+! ----- Search by computing the minimum distance between the barycenters
+ call ap_infast_n(mesh, newgeo, pair_tole, dist_ratio, nb_elem_mast, &
+ list_elem_mast, nb_elem_slav, list_elem_slav, elem_slav_flag, &
+ nb_mast_start, elem_mast_start, nb_slav_start, elem_slav_start, &
+ mastConxInvName, list_node_mast, nb_node_mast)
+ if (debug) then
+ WRITE (6, *) " Starting points (Master): ", nb_mast_start, elem_mast_start
+ WRITE (6, *) " Starting points (Slave) : ", nb_slav_start, elem_slav_start
end if
if (nb_slav_start == 0) then
@@ -229,9 +228,9 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
if (debug) then
call jenuno(jexnum(mesh//'.NOMMAI', elem_slav_nume), elem_slav_name)
- write (*, *) "Current slave element: ", elem_slav_nume, elem_slav_name, &
- '(type : ', elem_slav_code, ')'
- write (*, *) elem_slav_coor(1:3*elem_slav_nbnode)
+ write (*, *) "Current slave element : ", elem_slav_nume
+ write (6, *) " Coordinates (global frame): ", &
+ elem_slav_coor(1:3*elem_slav_nbnode)
end if
!
! ----- Number of neighbours
@@ -251,6 +250,7 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
end if
!
if (debug) then
+ write (6, *) "Potential number of neighbours: ", nb_slav_neigh
do i_slav_neigh = 1, nb_slav_neigh
elem_nume = v_sdappa_slne((elem_slav_indx-1)*4+i_slav_neigh)
if (elem_nume .ne. 0) then
@@ -258,7 +258,7 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
else
elem_name = 'None'
end if
- write (*, *) "Current slave element neighbours: ", elem_name
+ write (6, *) "Neighbour (", i_slav_neigh, "): ", elem_nume
end do
end if
!
@@ -269,19 +269,30 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
!
elem_start = elem_mast_start(1)
mast_find_indx = elem_start+1-mast_indx_mini
-!
+ if (debug) then
+ WRITE (6, *) "Avant décalage"
+ WRITE (6, *) " => ", nb_mast_start, elem_mast_start(1:nb_mast_start)
+ end if
+
! ----- Shift list of master element start
!
do i_mast_start = 1, nb_mast_start-1
elem_mast_start(i_mast_start) = elem_mast_start(i_mast_start+1)
end do
nb_mast_start = nb_mast_start-1
+ if (debug) then
+ WRITE (6, *) "Après décalage"
+ WRITE (6, *) " => ", nb_mast_start, elem_mast_start(1:nb_mast_start)
+ end if
!
! ----- Management of list of master elements: first element to seek
!
list_find_mast(1) = elem_start
nb_find_mast = 1
mast_find_flag(mast_find_indx) = 1
+ if (debug) then
+ write (6, *) "Master cell to start: ", elem_start
+ end if
!
! ----- Initialization list of contact pairs
!
@@ -304,8 +315,8 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
!
if (debug) then
call jenuno(jexnum(mesh//'.NOMMAI', elem_mast_nume), elem_name)
- write (*, *) ". Current master element: ", elem_mast_nume, elem_name, &
- '(type : ', elem_mast_type, ')'
+ write (*, *) "Current master element: ", elem_mast_nume
+ write (6, *) " Coordinates (global frame): "
end if
!
! ------------- Shift list of master elements (on supprime de la liste)
@@ -352,6 +363,13 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
!
if (inte_weight > pair_tole .and. iret == 0) then
nb_pair = nb_pair+1
+ if (debug) then
+ WRITE (6, *) "Add pair: ", nb_pair, &
+ "(", elem_slav_nume, "-", elem_mast_nume, ")"
+ WRITE (6, *) " Nb points integrations : ", nb_poin_inte
+ WRITE (6, *) " Coef. points integrations : ", poin_inte_sl
+ end if
+
ASSERT(nb_pair .le. nb_elem_slav*nb_elem_mast)
list_pair(2*(nb_pair-1)+1) = elem_slav_nume
list_pair(2*(nb_pair-1)+2) = elem_mast_nume
@@ -363,12 +381,15 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
(nb_pair-1)*SIZE_MAX_INTE_SL+SIZE_MAX_INTE_SL) = poin_inte_ma
!print*,"LIPTMA_APLC", li_pt_inte_ma((nb_pair-1)*SIZE_MAX_INTE_SL+1:&
! (nb_pair-1)*SIZE_MAX_INTE_SL+2)
+
+ call pairAdd(elem_slav_nume, elem_mast_nume, &
+ nb_poin_inte, li_pt_inte_sl, &
+ meshPairing)
end if
if (debug) then
write (*, *) ". Contact pair: ", elem_slav_nume, elem_mast_nume, &
" (weight: ", inte_weight, ", nb point inter: ", nb_poin_inte, ")"
-
end if
!
! --------- Find neighbour of current master element
@@ -393,6 +414,7 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
!
! ------------- Prepare next master element
!
+ ! WRITE (6, *) "Prepare next master element"
do i_mast_neigh = 1, nb_mast_neigh
elem_mast_neigh = v_sdappa_mane((elem_mast_indx-1)*4+i_mast_neigh)
elem_neigh_indx = elem_mast_neigh+1-mast_indx_mini
@@ -400,15 +422,30 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
mast_find_flag(elem_neigh_indx) == 0) then
list_find_mast(nb_find_mast+1) = elem_mast_neigh
nb_find_mast = nb_find_mast+1
+ if (debug) then
+ WRITE (6, *) " => added: ", nb_find_mast, &
+ list_find_mast(nb_find_mast)
+ end if
mast_find_flag(elem_neigh_indx) = 1
end if
end do
+
!
! ------------- Prepare next slave element: higher weight
!
+ if (debug) then
+ WRITE (6, *) "Prepare next slave element"
+ end if
do i_slav_neigh = 1, nb_slav_neigh
elem_slav_neigh = v_sdappa_slne((elem_slav_indx-1)*4+i_slav_neigh)
elem_neigh_indx = elem_slav_neigh+1-slav_indx_mini
+ if (debug) then
+ WRITE (6, *) " < Index:", i_slav_neigh
+ WRITE (6, *) " < cellNeighNume:", elem_slav_neigh
+ WRITE (6, *) " < cellNeighIndx: ", elem_neigh_indx
+ WRITE (6, *) " < cellSlavFlag: ", elem_slav_flag(elem_neigh_indx)
+ WRITE (6, *) " < inteNeigh: ", inte_neigh(i_slav_neigh)
+ end if
if (elem_slav_neigh .ne. 0 .and. &
inte_neigh(i_slav_neigh) == 1 &
.and. elem_slav_flag(elem_neigh_indx) .ne. 1 &
@@ -422,6 +459,9 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
!if (weight_test > list_slav_weight(i_slav_neigh).and.&
! weight_test > pair_tole) then
list_slav_master(i_slav_neigh) = elem_mast_nume
+ if (debug) then
+ WRITE (6, *) " => added: ", elem_mast_nume
+ end if
! list_slav_weight(i_slav_neigh) = weight_test
!end if
end if
@@ -434,7 +474,7 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
! ----- Next elements
!
if (debug) then
- write (*, *) 'Next elements - Nb: ', nb_slav_neigh
+ write (*, *) 'Prepare next elements - Nb: ', nb_slav_neigh
end if
do i_slav_neigh = 1, nb_slav_neigh
elem_slav_neigh = v_sdappa_slne((elem_slav_indx-1)*4+i_slav_neigh)
@@ -459,21 +499,8 @@ subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
!pair_exist = ASTER_FALSE
end do
-!
-!----- save results
-!
- nb_pair_zone = nb_pair
- if (nb_pair_zone > 0) then
- call wkvect(list_pair_zone, 'G V I', 2*nb_pair_zone, jtab)
- zi(jtab-1+1:jtab-1+2*nb_pair_zone) = list_pair(1:2*nb_pair_zone)
- call wkvect(list_nbptit_zone, 'G V I', nb_pair_zone, jtab)
- zi(jtab-1+1:jtab-1+nb_pair_zone) = li_nb_pt_inte_sl(1:nb_pair_zone)
- call wkvect(list_ptitsl_zone, 'G V R', 16*nb_pair_zone, jtab)
- zr(jtab-1+1:jtab-1+16*nb_pair_zone) = li_pt_inte_sl(1:16*nb_pair_zone)
- end if
-!
-!--- DEALLOCATE
-!
+
+! - DEALLOCATE
AS_DEALLOCATE(vi=mast_find_flag)
AS_DEALLOCATE(vi=elem_slav_flag)
AS_DEALLOCATE(vr=li_pt_inte_sl)
diff --git a/bibfor/cont_pair/lcptga.F90 b/bibfor/cont_pair/lcptga.F90
index 3a56633f95c..f4a623d1334 100644
--- a/bibfor/cont_pair/lcptga.F90
+++ b/bibfor/cont_pair/lcptga.F90
@@ -1,5 +1,5 @@
! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
! This file is part of code_aster.
!
! code_aster is free software: you can redistribute it and/or modify
@@ -60,10 +60,8 @@ subroutine lcptga(elem_dime, tria_coor, gauss_family, &
!
model_ndim = elem_dime-1
nb_gauss = 0
- do i_dime = 1, model_ndim
- gauss_coor(i_dime, 1:12) = 0.d0
- end do
- gauss_weight(1:12) = 0.d0
+ gauss_coor = 0.d0
+ gauss_weight = 0.d0
!
! - Select reference geometry for auxiliary parametric space
!
diff --git a/bibfor/include/Contact_type.h b/bibfor/include/Contact_type.h
index ec1d2446092..50fa8253cd2 100644
--- a/bibfor/include/Contact_type.h
+++ b/bibfor/include/Contact_type.h
@@ -16,21 +16,14 @@
! along with code_aster. If not, see .
! --------------------------------------------------------------------
!
-! Contact data structure : Parameters <-> integer definitions
-! -------------------------------------------------------------------------
+! ==================================================================================================
!
+! Algorithm
+!
+! ==================================================================================================
#define ALGO_FIXE 0
#define ALGO_NEWT 1
#define NB_DATA_CYCL 75
+! Total number of coordinates for intersection points (old one, to suppress)
#define SIZE_MAX_INTE_SL 16
-
-! Projection type
-! -------------------------------------------------------------------------
-#define PROJ_TYPE_NODE 0
-#define PROJ_TYPE_FIXE 1
-
-! Projection algo parameters
-! -------------------------------------------------------------------------
-#define PROJ_ALGO_NONE 0
-#define PROJ_ALGO_GAPI 1
diff --git a/bibfor/include/asterfort/aplcpgn.h b/bibfor/include/asterfort/aplcpgn.h
index 492700a4531..eca01fb5382 100644
--- a/bibfor/include/asterfort/aplcpgn.h
+++ b/bibfor/include/asterfort/aplcpgn.h
@@ -1,5 +1,5 @@
! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2022 - EDF R&D - www.code-aster.org
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
! This file is part of code_aster.
!
! code_aster is free software: you can redistribute it and/or modify
@@ -15,19 +15,19 @@
! You should have received a copy of the GNU General Public License
! along with code_aster. If not, see .
! --------------------------------------------------------------------
-
-!
-!
#include "asterf_types.h"
!
interface
- subroutine aplcpgn(mesh, newgeo, zone, pair_method, pair_tole, dist_ratio, &
- nb_elem_mast, list_elem_mast, nb_elem_slav, list_elem_slav, list_node_mast,&
- nb_node_mast , nb_pair_zone, list_pair_zone, list_nbptit_zone,&
- list_ptitsl_zone)
+ subroutine aplcpgn(mesh, newgeo, &
+ mastConxInvName, mastNeighName, slavNeighName, &
+ pair_tole, dist_ratio, &
+ nb_elem_mast, list_elem_mast, nb_elem_slav, list_elem_slav, list_node_mast, &
+ nb_node_mast, meshPairing)
+ use MeshPairing_module
character(len=8), intent(in) :: mesh
character(len=19), intent(in) :: newgeo
- character(len=19), intent(in) :: zone
+ character(len=24), intent(in) :: mastConxInvName
+ character(len=24), intent(in) :: mastNeighName, slavNeighName
real(kind=8), intent(in) :: pair_tole, dist_ratio
integer, intent(in) :: nb_elem_slav
integer, intent(in) :: nb_elem_mast
@@ -35,9 +35,6 @@ interface
integer, intent(in) :: list_elem_mast(nb_elem_mast)
integer, intent(in) :: list_elem_slav(nb_elem_slav)
integer, intent(in) :: list_node_mast(nb_node_mast)
- integer, intent(out) :: nb_pair_zone
- character(len=19), intent(in) :: list_pair_zone, list_nbptit_zone
- character(len=19), intent(in) :: list_ptitsl_zone
- character(len=24), intent(in) :: pair_method
+ type(MESH_PAIRING), intent(inout) :: meshPairing
end subroutine aplcpgn
end interface
diff --git a/bibfor/include/asterfort/getInterCont.h b/bibfor/include/asterfort/getInterCont.h
new file mode 100644
index 00000000000..51b0049716c
--- /dev/null
+++ b/bibfor/include/asterfort/getInterCont.h
@@ -0,0 +1,25 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+#include "asterfort/mesh_pairing_type.h"
+!
+interface
+ subroutine getInterCont(nbPoinInte, poinInteSlav)
+ integer, intent(out) :: nbPoinInte
+ real(kind=8), intent(out) :: poinInteSlav(2, MAX_NB_INTE)
+ end subroutine getInterCont
+end interface
diff --git a/bibfor/include/asterfort/getQuadCont.h b/bibfor/include/asterfort/getQuadCont.h
index 8421093fde1..fab9359fbd2 100644
--- a/bibfor/include/asterfort/getQuadCont.h
+++ b/bibfor/include/asterfort/getQuadCont.h
@@ -1,5 +1,5 @@
! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2022 - EDF R&D - www.code-aster.org
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
! This file is part of code_aster.
!
! code_aster is free software: you can redistribute it and/or modify
@@ -15,19 +15,25 @@
! You should have received a copy of the GNU General Public License
! along with code_aster. If not, see .
! --------------------------------------------------------------------
-!
#include "asterf_types.h"
+#include "asterfort/mesh_pairing_type.h"
!
interface
- subroutine getQuadCont(elem_dime, l_axis, &
- nb_node_slav, elem_slav_code, elem_slav_coor,&
- elem_mast_code, &
- nb_qp, coor_qp , weight_qp )
- integer, intent(in) :: elem_dime, nb_node_slav
- aster_logical, intent(in) :: l_axis
+ subroutine getQuadCont(elem_dime, &
+ elem_slav_code, elem_mast_code, &
+ nbPoinInte, poinInteSlav, &
+ nb_qp, coor_qp, &
+ l_axis_, nb_node_slav_, elem_slav_coor_, &
+ weight_qp_)
+ integer, intent(in) :: elem_dime
character(len=8), intent(in) :: elem_slav_code, elem_mast_code
- real(kind=8), intent(in) :: elem_slav_coor(3, 9)
- real(kind=8), intent(out) :: coor_qp(2, 48), weight_qp(48)
+ integer, intent(in) :: nbPoinInte
+ real(kind=8), intent(in) :: poinInteSlav(2, MAX_NB_INTE)
+ real(kind=8), intent(out) :: coor_qp(2, 48)
integer, intent(out) :: nb_qp
+ integer, optional, intent(in) :: nb_node_slav_
+ real(kind=8), optional, intent(in) :: elem_slav_coor_(3, 9)
+ aster_logical, optional, intent(in) :: l_axis_
+ real(kind=8), optional, intent(out) :: weight_qp_(48)
end subroutine getQuadCont
end interface
diff --git a/bibfor/include/asterfort/extrs1.h b/bibfor/include/asterfort/inteCellAreaWrap.h
similarity index 62%
rename from bibfor/include/asterfort/extrs1.h
rename to bibfor/include/asterfort/inteCellAreaWrap.h
index bcd6d15686a..06c378def71 100644
--- a/bibfor/include/asterfort/extrs1.h
+++ b/bibfor/include/asterfort/inteCellAreaWrap.h
@@ -1,5 +1,5 @@
! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2017 - EDF R&D - www.code-aster.org
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
! This file is part of code_aster.
!
! code_aster is free software: you can redistribute it and/or modify
@@ -15,21 +15,13 @@
! You should have received a copy of the GNU General Public License
! along with code_aster. If not, see .
! --------------------------------------------------------------------
-
-!
+#include "asterfort/mesh_pairing_type.h"
!
interface
- subroutine extrs1(resu0, nbrang, nuordr, nbpara, nompar,&
- nbarch, nuarch, nbexcl, chexcl, nbnosy)
- character(len=*) :: resu0
- integer :: nbrang
- integer :: nuordr(*)
- integer :: nbpara
- character(len=16) :: nompar(*)
- integer :: nbarch
- integer :: nuarch(*)
- integer :: nbexcl
- character(len=16) :: chexcl(*)
- integer :: nbnosy
- end subroutine extrs1
+ subroutine inteCellAreaWrap(spaceDime, nbPoinInte, poinInteSlav, &
+ inteArea)
+ integer, intent(in) :: spaceDime, nbPoinInte
+ real(kind=8), intent(in) :: poinInteSlav(2, MAX_NB_INTE)
+ real(kind=8), intent(out) :: inteArea
+ end subroutine inteCellAreaWrap
end interface
diff --git a/bibfor/include/asterfort/intePoinCoorWrap.h b/bibfor/include/asterfort/intePoinCoorWrap.h
new file mode 100644
index 00000000000..db9dafbc7bb
--- /dev/null
+++ b/bibfor/include/asterfort/intePoinCoorWrap.h
@@ -0,0 +1,27 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+#include "asterfort/mesh_pairing_type.h"
+!
+interface
+ subroutine intePoinCoorWrap(mesh, baseName, iPair, poinInteReal)
+ character(len=8), intent(in) :: mesh
+ character(len=24), intent(in) :: baseName
+ integer, intent(in) :: iPair
+ real(kind=8), intent(out) :: poinInteReal(3, MAX_NB_INTE)
+ end subroutine intePoinCoorWrap
+end interface
diff --git a/bibfor/include/asterfort/latrco.h b/bibfor/include/asterfort/latrco.h
index 6a3b3e9018e..1cabc7f46af 100644
--- a/bibfor/include/asterfort/latrco.h
+++ b/bibfor/include/asterfort/latrco.h
@@ -1,5 +1,5 @@
! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2022 - EDF R&D - www.code-aster.org
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
! This file is part of code_aster.
!
! code_aster is free software: you can redistribute it and/or modify
@@ -15,14 +15,13 @@
! You should have received a copy of the GNU General Public License
! along with code_aster. If not, see .
! --------------------------------------------------------------------
-
-!
+#include "mesh_pairing_type.h"
!
interface
- subroutine latrco(i_tria, nb_poin_inte, poin_inte, tria_coor)
- integer, intent(in) :: i_tria
- integer, intent(in) :: nb_poin_inte
- real(kind=8), intent(in) :: poin_inte(2,8)
- real(kind=8), intent(out) :: tria_coor(2,3)
+ subroutine latrco(iTria, nbPoinInte, poinInte, triaCoorPara)
+ integer, intent(in) :: iTria
+ integer, intent(in) :: nbPoinInte
+ real(kind=8), intent(in) :: poinInte(2, MAX_NB_INTE)
+ real(kind=8), intent(out) :: triaCoorPara(2, 3)
end subroutine latrco
end interface
diff --git a/bibfor/include/asterfort/mesh_pairing_type.h b/bibfor/include/asterfort/mesh_pairing_type.h
new file mode 100644
index 00000000000..ccc37ea3111
--- /dev/null
+++ b/bibfor/include/asterfort/mesh_pairing_type.h
@@ -0,0 +1,58 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+
+! ==================================================================================================
+!
+! Pairing/intersection
+!
+! ==================================================================================================
+! Method of pairing
+#define PAIR_FAST 1
+#define PAIR_OLD 2
+#define PAIR_ROBUST 3
+
+! Maximum number of neighbours of a cell
+#define MAX_NB_NEIGH 4
+
+! Maximum number of intersection points
+#define MAX_NB_INTE 8
+
+! Maximum number of quadrature points
+#define MAX_NB_QUAD 48
+
+! ==================================================================================================
+!
+! Error code for pairing
+!
+! ERR_CELL_ORTH: cells are orthognal
+! ERR_CELL_OOR : out of range (greater than DIST_RATIO)
+! ERR_PAIR_PROJ: error during projection
+! ERR_INTE_VOID: intersection is not correct
+! ERR_PAIR_SLAV: projected slave nodes are not inside master cell
+! ERR_PAIR_MAST: master nodes are not inside projected slave cell
+! ERR_CELL_DEGE: cell is degenerated
+!
+! ==================================================================================================
+#define ERR_PAIR_NONE 0
+#define ERR_CELL_ORTH 1
+#define ERR_CELL_OOR 2
+#define ERR_PAIR_PROJ 3
+#define ERR_INTE_VOID 4
+#define ERR_PAIR_SLAV 5
+#define ERR_PAIR_MAST 6
+#define ERR_CELL_DEGE 7
diff --git a/bibfor/include/asterfort/pairWrap.h b/bibfor/include/asterfort/pairWrap.h
new file mode 100644
index 00000000000..2da628b541b
--- /dev/null
+++ b/bibfor/include/asterfort/pairWrap.h
@@ -0,0 +1,40 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+!
+interface
+ subroutine pairWrap(method, &
+ mesh, newgeo, mastConxInvName, &
+ mastNeighName, slavNeighName, &
+ pairTole, distRatio, verbosity, &
+ nbCellMast, listCellMast, &
+ nbCellSlav, listCellSlav, &
+ nbNodeMast, listNodeMast, &
+ nbPairZone, baseName)
+ integer, intent(in) :: method
+ character(len=8), intent(in) :: mesh
+ character(len=24), intent(in) :: newgeo, mastConxInvName
+ character(len=24), intent(in) :: mastNeighName, slavNeighName
+ real(kind=8), intent(in) :: pairTole, distRatio
+ integer, intent(in) :: verbosity
+ integer, intent(in) :: nbCellMast, listCellMast(nbCellMast)
+ integer, intent(in) :: nbCellSlav, listCellSlav(nbCellSlav)
+ integer, intent(in) :: nbNodeMast, listNodeMast(nbNodeMast)
+ integer, intent(out) :: nbPairZone
+ character(len=8), intent(in) :: baseName
+ end subroutine pairWrap
+end interface
diff --git a/bibfor/include/asterfort/quadPoinCoorWrap.h b/bibfor/include/asterfort/quadPoinCoorWrap.h
new file mode 100644
index 00000000000..81488ddff03
--- /dev/null
+++ b/bibfor/include/asterfort/quadPoinCoorWrap.h
@@ -0,0 +1,29 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+#include "asterfort/mesh_pairing_type.h"
+!
+interface
+ subroutine quadPoinCoorWrap(mesh, baseName, iPair, &
+ nbPoinQuad, poinQuad)
+ character(len=8), intent(in) :: mesh
+ character(len=24), intent(in) :: baseName
+ integer, intent(in) :: iPair
+ integer, intent(out) :: nbPoinQuad
+ real(kind=8), intent(out) :: poinQuad(3, MAX_NB_QUAD)
+ end subroutine quadPoinCoorWrap
+end interface
diff --git a/bibfor/load/load_neum_prep.F90 b/bibfor/load/load_neum_prep.F90
index 537787bb0e1..4a503d31fea 100644
--- a/bibfor/load/load_neum_prep.F90
+++ b/bibfor/load/load_neum_prep.F90
@@ -89,7 +89,7 @@ subroutine load_neum_prep(model, cara_elem, mate, mateco, load_type, inst_prev,
!
! --------------------------------------------------------------------------------------------------
!
- character(len=24) :: chgeom, chcara(18), chharm, chtime, chinst_curr, chinst_prev
+ character(len=24) :: chgeom, chcara(18), chharm, chtime
character(len=19) :: ligrel_model
character(len=8) :: nomcmp(3), mesh
real(kind=8) :: time(3)
@@ -112,30 +112,19 @@ subroutine load_neum_prep(model, cara_elem, mate, mateco, load_type, inst_prev,
! - Elementary characteristics fields
!
call mecara(cara_elem, chcara)
-!
+
! - Times field
-!
- if (load_type .ne. 'Dead') then
- nomcmp(1) = 'INST'
- chinst_curr = '&&VECHME.CH_INST_R'
- call mecact('V', chinst_curr, 'LIGREL', ligrel_model, 'INST_R ', &
- ncmp=1, nomcmp=nomcmp(1), sr=inst_curr)
- chinst_prev = '&&VECHME.CH_INST_M'
- call mecact('V', chinst_prev, 'LIGREL', ligrel_model, 'INST_R ', &
- ncmp=1, nomcmp=nomcmp(1), sr=inst_prev)
- nomcmp(1) = 'INST'
- nomcmp(2) = 'DELTAT'
- nomcmp(3) = 'THETA'
- time(1) = inst_curr
+ nomcmp(1) = 'INST'
+ nomcmp(2) = 'DELTAT'
+ nomcmp(3) = 'THETA'
+ if (load_type .eq. 'Dead') then
+ time(1) = inst_prev
time(2) = inst_curr-inst_prev
time(3) = inst_theta
call mecact('V', chtime, 'LIGREL', ligrel_model, 'INST_R ', &
ncmp=3, lnomcmp=nomcmp, vr=time)
else
- nomcmp(1) = 'INST'
- nomcmp(2) = 'DELTAT'
- nomcmp(3) = 'THETA'
- time(1) = inst_prev
+ time(1) = inst_curr
time(2) = inst_curr-inst_prev
time(3) = inst_theta
call mecact('V', chtime, 'LIGREL', ligrel_model, 'INST_R ', &
@@ -211,12 +200,6 @@ subroutine load_neum_prep(model, cara_elem, mate, mateco, load_type, inst_prev,
nb_in_prep = nb_in_prep+1
lpain(nb_in_prep) = 'PDEPLPR'
lchin(nb_in_prep) = disp_cumu_inst(1:19)
- nb_in_prep = nb_in_prep+1
- lpain(nb_in_prep) = 'PINSTMR'
- lchin(nb_in_prep) = chinst_prev(1:19)
- nb_in_prep = nb_in_prep+1
- lpain(nb_in_prep) = 'PINSTPR'
- lchin(nb_in_prep) = chinst_curr(1:19)
end if
if (load_type .eq. 'Suiv') then
nb_in_prep = nb_in_prep+1
@@ -226,12 +209,6 @@ subroutine load_neum_prep(model, cara_elem, mate, mateco, load_type, inst_prev,
lpain(nb_in_prep) = 'PDEPLPR'
lchin(nb_in_prep) = disp_cumu_inst(1:19)
nb_in_prep = nb_in_prep+1
- lpain(nb_in_prep) = 'PINSTMR'
- lchin(nb_in_prep) = chinst_prev(1:19)
- nb_in_prep = nb_in_prep+1
- lpain(nb_in_prep) = 'PINSTPR'
- lchin(nb_in_prep) = chinst_curr(1:19)
- nb_in_prep = nb_in_prep+1
lpain(nb_in_prep) = 'PCOMPOR'
lchin(nb_in_prep) = compor(1:19)
if (present(vite_curr_)) then
diff --git a/bibfor/mesh/inteCellAreaWrap.F90 b/bibfor/mesh/inteCellAreaWrap.F90
new file mode 100644
index 00000000000..231e1657cc9
--- /dev/null
+++ b/bibfor/mesh/inteCellAreaWrap.F90
@@ -0,0 +1,64 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+!
+subroutine inteCellAreaWrap(mesh, nbPoinInte, poinInteSlav, &
+ inteArea)
+!
+ use MeshPairing_module
+!
+ implicit none
+!
+#include "asterf_types.h"
+#include "asterfort/assert.h"
+#include "asterfort/dismoi.h"
+#include "asterfort/mesh_pairing_type.h"
+!
+ character(len=8), intent(in) :: mesh
+ integer, intent(in) :: nbPoinInte
+ real(kind=8), intent(in) :: poinInteSlav(2, MAX_NB_INTE)
+ real(kind=8), intent(out) :: inteArea
+!
+! --------------------------------------------------------------------------------------------------
+!
+! Pairing segment to segment
+!
+! Compute area of intersection
+!
+! --------------------------------------------------------------------------------------------------
+!
+! In mesh : mesh
+! In nbPoinInte : number of intersection points
+! In poinInte : list of intersection points
+! Out inteArea : area of intersection
+!
+! --------------------------------------------------------------------------------------------------
+!
+ integer :: spaceDime
+!
+! --------------------------------------------------------------------------------------------------
+!
+ call dismoi('DIM_GEOM', mesh, 'MAILLAGE', repi=spaceDime)
+ if (spaceDime .eq. 2) then
+ spaceDime = 2
+ else
+ spaceDime = 3
+ end if
+ inteArea = 0.d0
+ call inteCellArea(spaceDime, nbPoinInte, poinInteSlav, inteArea)
+!
+end subroutine
diff --git a/bibfor/mesh/intePoinCoorWrap.F90 b/bibfor/mesh/intePoinCoorWrap.F90
new file mode 100644
index 00000000000..dba253c6a0a
--- /dev/null
+++ b/bibfor/mesh/intePoinCoorWrap.F90
@@ -0,0 +1,77 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+!
+subroutine intePoinCoorWrap(mesh, nodeCoorName, baseName, iPair, &
+ poinInteReal)
+!
+ use MeshPairing_module
+ use mesh_type
+ use mesh_cell_module
+!
+ implicit none
+!
+#include "asterf_types.h"
+#include "asterfort/assert.h"
+#include "asterfort/jeveuo.h"
+#include "asterfort/mesh_pairing_type.h"
+#include "jeveux.h"
+!
+ character(len=8), intent(in) :: mesh
+ character(len=24), intent(in) :: nodeCoorName
+ character(len=24), intent(in) :: baseName
+ integer, intent(in) :: iPair
+ real(kind=8), intent(out) :: poinInteReal(3, MAX_NB_INTE)
+!
+! --------------------------------------------------------------------------------------------------
+!
+! Pairing segment to segment
+!
+! Compute point of intersection in global space
+!
+! --------------------------------------------------------------------------------------------------
+!
+! In mesh : mesh
+! In baseName : JEVEUX base name for output objects
+! In nodeCoorName : JEVEUX name for coordinates of nodes
+! In iPair : index of pair
+! Out poinInteReal : coordinates of intersection points en global space
+!
+! --------------------------------------------------------------------------------------------------
+!
+ type(CELL_GEOM) :: cellSlav
+ integer :: nbPoinInte
+ real(kind=8) :: poinInteSlav(2, MAX_NB_INTE)
+ real(kind=8), pointer :: nodeCoor(:) => null()
+!
+! --------------------------------------------------------------------------------------------------
+!
+ poinInteReal = 0.d0
+
+! - Access to updated geometry
+ call jeveuo(nodeCoorName(1:19)//'.VALE', 'L', vr=nodeCoor)
+
+! - Access to pair objects
+ call getPairJV(mesh, baseName, nodeCoor, iPair+1, cellSlav_=cellSlav)
+
+! - Get coordinates of intersection points in slave parametric space
+ call getInteJV(baseName, iPair+1, nbPoinInte, poinInteSlav)
+
+! - Project coordinates
+ call intePoinCoor(cellSlav, nbPoinInte, poinInteSlav, poinInteReal)
+!
+end subroutine
diff --git a/bibfor/mesh/mesh_cell_module.F90 b/bibfor/mesh/mesh_cell_module.F90
new file mode 100644
index 00000000000..ebdd54e859a
--- /dev/null
+++ b/bibfor/mesh/mesh_cell_module.F90
@@ -0,0 +1,1120 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+!
+! ==================================================================================================
+!
+! Module for cells in mesh
+!
+! ==================================================================================================
+!
+module mesh_cell_module
+! ==================================================================================================
+ use mesh_type
+! ==================================================================================================
+ implicit none
+! ==================================================================================================
+ public :: cellCreate
+ public :: cellCompTang, cellCompNorm, cellCompBaseAtPoint, cellCompNormAtBary
+ public :: cellCompDiam, cellCompBary, cellCompCenterGlob
+ public :: cellDebug, cellCopyType, cellPoinParaToGlob
+ public :: cellPoinInside, cellPoinAdjust
+ public :: cellSetType
+ private :: cellSetCoorGlob, cellSetLine, cellSetUndef
+ private :: cellCompCenterPara, cellSetNbNeigh
+ private :: cellPoinAdjustSeg, cellPoinAdjustTria, cellPoinAdjustQuad
+! ==================================================================================================
+ private
+#include "asterc/r8nnem.h"
+#include "asterf_types.h"
+#include "asterfort/assert.h"
+#include "asterfort/elrfdf.h"
+#include "asterfort/elrfno.h"
+#include "asterfort/elrfvf.h"
+#include "asterfort/jenuno.h"
+#include "asterfort/jexnum.h"
+#include "asterfort/normev.h"
+#include "asterfort/provec.h"
+#include "jeveux.h"
+#include "MeshTypes_type.h"
+! ==================================================================================================
+contains
+! --------------------------------------------------------------------------------------------------
+!
+! cellCreate
+!
+! Create a cell
+!
+! In cellNume : index of cell in mesh
+! Ptr nodeCoor : pointer to coordinates of nodes
+! Ptr meshTypeGeom : pointer to type of cells in mesh
+! Ptr meshConx : pointers to connectivity of mesh
+! meshConxCumu
+! Out cellGeom : general geometric properties of cell
+! Out cellGeomLine : general geometric properties of cell after linearization
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellCreate(cellNume, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ cellGeom, cellGeomLine_)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ integer, intent(in) :: cellNume
+ real(kind=8), pointer :: nodeCoor(:)
+ integer, pointer :: meshTypeGeom(:), meshConx(:), meshConxCumu(:)
+ type(CELL_GEOM), intent(out) :: cellGeom
+ type(CELL_GEOM), optional, intent(out) :: cellGeomLine_
+! ------------------------------------------------------------------------------------------------
+!
+
+! ----- Set type of cell from mesh
+ call cellSetType(meshTypeGeom, cellNume, cellGeom)
+
+! ----- Set coordinates of cell (in global space)
+ call cellSetCoorGlob(cellNume, nodeCoor, &
+ meshConx, meshConxCumu, &
+ cellGeom)
+
+! ----- Compute barycenters
+ call cellCompBary(cellGeom)
+
+! ----- Compute diameter
+ call cellCompDiam(cellGeom)
+
+! ----- Linearize cell
+ if (present(cellGeomLine_)) then
+ call cellSetLine(cellGeom, cellGeomLine_)
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellSetType
+!
+! Get type of cell
+!
+! Ptr meshTypeGeom : geometric type of cells
+! In cellNume : index of cell in mesh
+! IO cellGeom : geometric properties of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellSetType(meshTypeGeom, cellNume, cellGeom)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ integer, pointer :: meshTypeGeom(:)
+ integer, intent(in) :: cellNume
+ type(CELL_GEOM), intent(inout) :: cellGeom
+! ----- Local
+ integer :: cellTypeNume, nbNode, nbNodeS, cellDime
+ character(len=8) :: cellTypeName
+! ------------------------------------------------------------------------------------------------
+!
+ cellTypeNume = meshTypeGeom(cellNume)
+ call jenuno(jexnum('&CATA.TM.NOMTM', cellTypeNume), cellTypeName)
+ select case (cellTypeName)
+ case ('SEG2')
+ cellGeom%cellCode = 'SE2'
+ case ('SEG3')
+ cellGeom%cellCode = 'SE3'
+ case ('TRIA3')
+ cellGeom%cellCode = 'TR3'
+ case ('TRIA6')
+ cellGeom%cellCode = 'TR6'
+ case ('QUAD4')
+ cellGeom%cellCode = 'QU4'
+ case ('QUAD8')
+ cellGeom%cellCode = 'QU8'
+ case ('QUAD9')
+ cellGeom%cellCode = 'QU9'
+ case default
+ ASSERT(ASTER_FALSE)
+ end select
+
+! ----- Prov: all cells are skin's ones
+ cellGeom%isSkin = ASTER_TRUE
+
+! ----- For standard cells
+ call elrfno(cellGeom%cellCode, nbNode, nbNodeS, cellDime, nodeCoor=cellGeom%coorNodePara)
+ cellGeom%nbNode = nbNode
+ cellGeom%cellDime = cellDime
+ cellGeom%isLinear = (nbNode .eq. nbNodeS)
+ if (cellGeom%isSkin) then
+ call cellSetNbNeigh(cellGeom)
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellSetCoorGlob
+!
+! Set coordinates of cell (in global reference frame)
+!
+! In cellNume : index of cell in mesh
+! Ptr nodeCoor : pointer to coordinates of nodes for this cell
+! Ptr meshConnex : pointer to connectivity of mesh
+! Ptr meshConnexCumu : pointer to connectivity of mesh
+! IO cellGeom : geometric properties of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellSetCoorGlob(cellNume, nodeCoor, &
+ meshConnex, meshConnexCumu, &
+ cellGeom)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ integer, intent(in) :: cellNume
+ real(kind=8), pointer :: nodeCoor(:)
+ integer, pointer :: meshConnex(:), meshConnexCumu(:)
+ type(CELL_GEOM), intent(inout) :: cellGeom
+! ----- Local
+ integer :: iNode, iDime, nodeNume
+! ------------------------------------------------------------------------------------------------
+!
+ cellGeom%coorNodeGlob = 0.d0
+ do iNode = 1, cellGeom%nbNode
+ nodeNume = meshConnex(meshConnexCumu(cellNume)-1+iNode)
+ do iDime = 1, 3
+ cellGeom%coorNodeGlob(iDime, iNode) = &
+ nodeCoor(3*(nodeNume-1)+iDime)
+ end do
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellSetLine
+!
+! Linearization of cell
+!
+! In cellGeom : geometric properties of cell
+! Out cellGeomLine : geometry of cell after linearization
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellSetLine(cellGeom, cellGeomLine)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellGeom
+ type(CELL_GEOM), intent(out) :: cellGeomLine
+! ------------------------------------------------------------------------------------------------
+!
+ cellGeomLine = cellGeom
+
+! ----- Change support
+ if (cellGeom%cellCode .eq. 'SE2' .or. cellGeom%cellCode .eq. 'SE3') then
+ cellGeomLine%cellCode = 'SE2'
+ cellGeomLine%nbNode = 2
+ elseif (cellGeom%cellCode .eq. 'TR3' .or. cellGeom%cellCode .eq. 'TR6') then
+ cellGeomLine%cellCode = 'TR3'
+ cellGeomLine%nbNode = 3
+ else if (cellGeom%cellCode .eq. 'QU4' .or. &
+ cellGeom%cellCode .eq. 'QU8' .or. &
+ cellGeom%cellCode .eq. 'QU9') then
+ cellGeomLine%cellCode = 'QU4'
+ cellGeomLine%nbNode = 4
+ else
+ WRITE (6, *) "cellGeom%cellCode: ", cellGeom%cellCode
+ ASSERT(ASTER_FALSE)
+ end if
+ cellGeomLine%isLinear = ASTER_TRUE
+
+! ----- Change coordinates
+ cellGeomLine%coorNodeGlob(:, cellGeomLine%nbNode+1:MT_NNOMAX3D) = 0.d0
+ cellGeomLine%coorNodePara(:, cellGeomLine%nbNode+1:MT_NNOMAX3D) = 0.d0
+
+! ----- Update barycenter
+ call cellCompBary(cellGeomLine)
+
+! ----- Update diameter
+ call cellCompDiam(cellGeomLine)
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellSetUndef
+!
+! Set undefined values for cell
+!
+! IO cellGeom : geometric properties of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellSetUndef(cellGeom)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(inout) :: cellGeom
+! ------------------------------------------------------------------------------------------------
+!
+ cellGeom%diameter = r8nnem()
+ cellGeom%baryGlob = r8nnem()
+ cellGeom%baryPara = r8nnem()
+ cellGeom%coorNodeGlob = r8nnem()
+ cellGeom%coorNodePara = r8nnem()
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellCompTang
+!
+! Compute tangents on cell at current point
+!
+! In cellGeom : geometric properties of cell
+! In spaceDime : dimension of space (2 or 3)
+! In dShapeFunc : values of derivatives of shape functions at current point
+! Out tau1 : first tangent at current point
+! Out tau2 : second tangent at current point
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellCompTang(cellGeom, spaceDime, dShapeFunc, tau1, tau2)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellGeom
+ integer, intent(in) :: spaceDime
+ real(kind=8), intent(in) :: dShapeFunc(3, MT_NNOMAX3D)
+ real(kind=8), intent(out) :: tau1(3), tau2(3)
+! ----- Local
+ real(kind=8), parameter :: zero = 0.d0
+ integer :: iNode, iDime
+! ------------------------------------------------------------------------------------------------
+!
+ ASSERT(cellGeom%nbNode .le. MT_NNOMAX3D)
+ tau1 = zero
+ tau2 = zero
+ do iDime = 1, spaceDime
+ do iNode = 1, cellGeom%nbNode
+ tau1(iDime) = cellGeom%coorNodeGlob(iDime, iNode)*dShapeFunc(1, iNode)+tau1(iDime)
+ if (spaceDime .eq. 3) then
+ tau2(iDime) = cellGeom%coorNodeGlob(iDime, iNode)*dShapeFunc(2, iNode)+ &
+ tau2(iDime)
+ end if
+ end do
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellCompBaseAtPoint
+!
+! Compute base at point (outward normal)
+!
+! In cellGeom : geometric properties of cell
+! In spaceDime : dimension of space (2 or 3)
+! In poinCoorPara : coordinates of point in parametric space
+! Out baseExte : base on point (with outward normal)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellCompBaseAtPoint(cellGeom, spaceDime, poinCoorPara, baseExte)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellGeom
+ integer, intent(in) :: spaceDime
+ real(kind=8), intent(in) :: poinCoorPara(3)
+ type(CELL_SKIN_BASE), intent(out) :: baseExte
+! ----- Local
+ real(kind=8) :: dShapeFunc(3, MT_NNOMAX3D), tau1(3), tau2(3), norm(3)
+! ------------------------------------------------------------------------------------------------
+!
+ ASSERT(cellGeom%isSkin)
+ baseExte%spaceDime = spaceDime
+ baseExte%normIsExte = ASTER_TRUE
+ baseExte%norm = 0.d0
+ baseExte%tau = 0.d0
+ call elrfdf(cellGeom%cellCode, poinCoorPara, dShapeFunc)
+ call cellCompTang(cellGeom, spaceDime, dShapeFunc, tau1, tau2)
+ call cellCompNorm(spaceDime, tau1, tau2, norm)
+ baseExte%norm = -norm
+ baseExte%tau(:, 1) = tau1
+ baseExte%tau(:, 2) = tau2
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellCompNorm
+!
+! Compute norm
+!
+! In spaceDime : dimension of space (2 or 3)
+! In tau1 : first tangent
+! In tau2 : second tangent
+! Out norm : norm
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellCompNorm(spaceDime, tau1, tau2, norm)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ integer, intent(in) :: spaceDime
+ real(kind=8), intent(in) :: tau1(3), tau2(3)
+ real(kind=8), intent(out) :: norm(3)
+! ----- Local
+ real(kind=8) :: noor
+! ------------------------------------------------------------------------------------------------
+!
+ norm = 0.d0
+ noor = 0.d0
+ if (spaceDime .eq. 2) then
+ norm(1) = -tau1(2)
+ norm(2) = tau1(1)
+ norm(3) = 0.d0
+ else if (spaceDime .eq. 3) then
+ call provec(tau2, tau1, norm)
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ call normev(norm, noor)
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellPoinParaToGlob
+!
+! Change coordinates of a point in cell to global reference frame
+!
+! In cellGeom : geometric properties of cell
+! In poinCoorPara : coordinates of point in cell parametric frame
+! Out poinCoorGlob : coordinates of point in global reference frame
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellPoinParaToGlob(cellGeom, &
+ poinCoorPara, poinCoorGlob)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellGeom
+ real(kind=8), intent(in) :: poinCoorPara(2)
+ real(kind=8), intent(out) :: poinCoorGlob(3)
+! ----- Local
+ real(kind=8) :: shapeFunc(MT_NNOMAX3D)
+ integer :: iNode, iDime
+! ------------------------------------------------------------------------------------------------
+!
+ poinCoorGlob = 0.d0
+
+! ----- Get shape functions in parametric space
+ shapeFunc = 0.d0
+ call elrfvf(cellGeom%cellCode, poinCoorPara, shapeFunc)
+
+! ----- Change coordinates
+ do iDime = 1, 3
+ do iNode = 1, cellGeom%nbNode
+ poinCoorGlob(iDime) = poinCoorGlob(iDime)+ &
+ cellGeom%coorNodeGlob(iDime, iNode)*shapeFunc(iNode)
+ end do
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellCompCenterPara
+!
+! Compute center of cell in parametric space
+!
+! In cellGeom : geometric properties of cell
+! Out cellCentPara : center of cell in parametric space
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellCompCenterPara(cellGeom, cellCentPara)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellGeom
+ real(kind=8), intent(out) :: cellCentPara(3)
+! ----- Local
+ integer :: iNode
+! ------------------------------------------------------------------------------------------------
+!
+ cellCentPara = 0.d0
+ do iNode = 1, cellGeom%nbNode
+ cellCentPara = cellCentPara+cellGeom%coorNodePara(:, iNode)
+ end do
+ cellCentPara = cellCentPara/cellGeom%nbNode
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellCompCenterGlob
+!
+! Compute center of cell in global space
+!
+! In cellGeom : geometric properties of cell
+! Out cellCentPara : center of cell in parametric space
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellCompCenterGlob(cellGeom, cellCentGlob)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellGeom
+ real(kind=8), intent(out) :: cellCentGlob(3)
+! ----- Local
+ real(kind=8) :: cellCentPara(3)
+! ------------------------------------------------------------------------------------------------
+!
+ cellCentGlob = 0.d0
+ call cellCompCenterPara(cellGeom, cellCentPara)
+ call cellPoinParaToGlob(cellGeom, cellCentPara, cellCentGlob)
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellCompDiam
+!
+! Compute diameter of cell
+!
+! IO cellGeom : geometry of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellCompDiam(cellGeom)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(inout) :: cellGeom
+! ----- Locals
+ integer :: iNode, jNode
+ real(kind=8) :: length
+! ------------------------------------------------------------------------------------------------
+!
+ cellGeom%diameter = 0.d0
+ do iNode = 1, cellGeom%nbNode
+ do jNode = iNode+1, cellGeom%nbNode
+ length = norm2(cellGeom%coorNodeGlob(1:3, iNode)- &
+ cellGeom%coorNodeGlob(1:3, jNode))
+ cellGeom%diameter = max(cellGeom%diameter, length)
+ end do
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellCompBary
+!
+! Compute barycenters of cell
+!
+! In spaceDime : dimension of space (2 or 3)
+! IO cellGeom : geometry of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellCompBary(cellGeom)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(inout) :: cellGeom
+! ----- Local
+ real(kind=8) :: cellBaryPara(3)
+ integer :: iNode
+! ------------------------------------------------------------------------------------------------
+!
+ cellGeom%baryGlob = 0.d0
+ do iNode = 1, cellGeom%nbNode
+ cellGeom%baryGlob = cellGeom%baryGlob+ &
+ cellGeom%coorNodeGlob(:, iNode)
+ end do
+ cellGeom%baryGlob = cellGeom%baryGlob/real(cellGeom%nbNode, kind=8)
+ call cellCompCenterPara(cellGeom, cellBaryPara)
+ cellGeom%baryPara = cellBaryPara
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellCompNormAtBary
+!
+! Compute normal at barycenter of cell
+!
+! In spaceDime : dimension of space (2 or 3)
+! In cellGeom : geometric properties of cell
+! Out cellNormBary : normal at barycenter of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellCompNormAtBary(spaceDime, cellGeom, cellNormBary)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ integer, intent(in) :: spaceDime
+ type(CELL_GEOM), intent(in) :: cellGeom
+ real(kind=8), intent(out) :: cellNormBary(3)
+! ----- Local
+ real(kind=8) :: cellCentPara(3)
+ type(CELL_SKIN_BASE) :: baseExte
+! ------------------------------------------------------------------------------------------------
+!
+ cellNormBary = 0.d0
+ ASSERT(cellGeom%isSkin)
+
+! ----- Get center of cell in parametric space
+ cellCentPara = cellGeom%baryPara
+
+! ----- Compute base on point (outward normal)
+ call cellCompBaseAtPoint(cellGeom, spaceDime, cellCentPara, baseExte)
+ cellNormBary = baseExte%norm
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellSetNbNeigh
+!
+! Set number of neighbours of skin cell
+!
+! IO cellGeom : geometric properties of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellSetNbNeigh(cellGeom)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(inout) :: cellGeom
+! ----- Local
+ integer :: nbNeigh
+! ------------------------------------------------------------------------------------------------
+!
+ nbNeigh = 0
+ ASSERT(cellGeom%isSkin)
+ if (cellGeom%cellCode == 'SE2' .or. &
+ cellGeom%cellCode == 'SE3') then
+ nbNeigh = 2
+ elseif (cellGeom%cellCode == 'TR3' .or. &
+ cellGeom%cellCode == 'TR6' .or. &
+ cellGeom%cellCode == 'TR7') then
+ nbNeigh = 3
+ elseif (cellGeom%cellCode == 'QU4' .or. &
+ cellGeom%cellCode == 'QU8' .or. &
+ cellGeom%cellCode == 'QU9') then
+ nbNeigh = 4
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ cellGeom%nbNeigh = nbNeigh
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellDebug
+!
+! Print debug informations about cell
+!
+! In cellGeom : geometric properties of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellDebug(cellGeom)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellGeom
+! ----- Locals
+ integer :: iNode
+! ------------------------------------------------------------------------------------------------
+!
+ if (cellGeom%isLinear) then
+ WRITE (6, *) "Linéaire"
+ else
+ WRITE (6, *) "Quadratique"
+ end if
+ if (cellGeom%isSkin) then
+ WRITE (6, *) "Maille de bord"
+ else
+ WRITE (6, *) "Maille d'intérieur"
+ end if
+ WRITE (6, *) "Type :", cellGeom%cellCode
+ WRITE (6, *) "Dime :", cellGeom%cellDime
+ WRITE (6, *) "Nb node :", cellGeom%nbNode
+ do iNode = 1, cellGeom%nbNode
+ WRITE (6, *) "Node (", iNode, "): ", &
+ cellGeom%coorNodeGlob(1:3, iNode), " (global frame)"
+ WRITE (6, *) "Node (", iNode, "): ", &
+ cellGeom%coorNodePara(1:3, iNode), " (local frame)"
+ end do
+ WRITE (6, *) "Diameter :", cellGeom%diameter
+ WRITE (6, *) "Barycenter:", cellGeom%baryGlob, " (global frame)"
+ WRITE (6, *) "Barycenter:", cellGeom%baryPara, " (local frame)"
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellCopyType
+!
+! Create new cell with same geometric type
+!
+! In cellGeom : geometric properties of original cell
+! Out cellCopy : geometric properties of new cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellCopyType(cellOrig, cellCopy)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellOrig
+ type(CELL_GEOM), intent(out) :: cellCopy
+! ----- Locals
+
+! ------------------------------------------------------------------------------------------------
+!
+ cellCopy = cellOrig
+ call cellSetUndef(cellCopy)
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+
+! --------------------------------------------------------------------------------------------------
+!
+! cellPoinInside
+!
+! Detect if point is inside cell - With its own reference frame
+!
+! In toleInside : tolerance to detect
+! In cellGeom : geometric properties of cell
+! In poinCoorPara : parametric coordinates of point
+! Out poinIsInside
+!
+! --------------------------------------------------------------------------------------------------
+ function cellPoinInside(cellGeom, toleInside, poinCoorPara)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ aster_logical :: cellPoinInside
+ type(CELL_GEOM), intent(in) :: cellGeom
+ real(kind=8), intent(in) :: toleInside
+ real(kind=8), intent(in) :: poinCoorPara(2)
+! ----- Local
+ character(len=8) :: cellCode
+! ------------------------------------------------------------------------------------------------
+!
+ cellCode = cellGeom%cellCode
+ ASSERT(cellGeom%isSkin)
+ cellPoinInside = ASTER_FALSE
+ if (cellCode .eq. 'SE2' .or. cellCode .eq. 'SE3') then
+ if (poinCoorPara(1) .ge. (-1.d0-toleInside) .and. &
+ poinCoorPara(1) .le. (1.d0+toleInside)) then
+ cellPoinInside = ASTER_TRUE
+ end if
+ elseif (cellCode .eq. 'TR3' .or. cellCode .eq. 'TR6') then
+ if (poinCoorPara(1) .ge. -toleInside .and. &
+ poinCoorPara(2) .ge. -toleInside .and. &
+ (poinCoorPara(2)+poinCoorPara(1)) .le. (1.d0+toleInside)) then
+ cellPoinInside = ASTER_TRUE
+ end if
+ elseif (cellCode .eq. 'QU4' .or. cellCode .eq. 'QU8' .or. cellCode .eq. 'QU9') then
+ if (poinCoorPara(1) .ge. (-1.d0-toleInside) .and. &
+ poinCoorPara(1) .le. (1.d0+toleInside) .and. &
+ poinCoorPara(2) .ge. (-1.d0-toleInside) .and. &
+ poinCoorPara(2) .le. (1.d0+toleInside)) then
+ cellPoinInside = ASTER_TRUE
+ end if
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end function
+! --------------------------------------------------------------------------------------------------
+!
+! cellPoinAdjust
+!
+! Adjust parametric coordinates to be inside cell
+!
+! In cellGeom : geometric properties of cell
+! In projOutside : tolerance for projection outside cell
+! IO poinCoorPara : coordinates of point
+! Out projType : type of projection
+! 0 - No projection inside cell (point is inside)
+! 1 - Projection inside cell
+! 2 - No projection inside cell (to far away)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellPoinAdjust(cellGeom, projOutside, &
+ poinCoorPara, projType_)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellGeom
+ real(kind=8), intent(in) :: projOutside
+ real(kind=8), intent(inout) :: poinCoorPara(2)
+ integer, optional, intent(out) :: projType_
+! ----- Local
+ integer :: projType
+ character(len=8) :: cellCode
+! ------------------------------------------------------------------------------------------------
+!
+ projType = 0
+ cellCode = cellGeom%cellCode
+ ASSERT(cellGeom%isSkin)
+
+ if (cellCode(1:2) .eq. 'SE') then
+ call cellPoinAdjustSeg(projOutside, &
+ poinCoorPara, projType)
+ else if (cellCode(1:2) .eq. 'TR') then
+ call cellPoinAdjustTria(projOutside, &
+ poinCoorPara, projType)
+ else if (cellCode(1:2) .eq. 'QU') then
+ call cellPoinAdjustQuad(projOutside, &
+ poinCoorPara, projType)
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+!
+ if (present(projType_)) then
+ projType_ = projType
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellPoinAdjustSeg
+!
+! Adjust parametric coordinates to be inside cell when cell is segment
+!
+! In projOutside : tolerance for projection outside cell
+! IO poinCoorPara : coordinates of point
+! Out projType : type of projection
+! 0 - No projection inside cell (point is inside)
+! 1 - Projection inside cell
+! 2 - No projection inside cell (to far away)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellPoinAdjustSeg(projOutside, &
+ poinCoorPara, projType)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ real(kind=8), intent(in) :: projOutside
+ real(kind=8), intent(inout) :: poinCoorPara(2)
+ integer, intent(out) :: projType
+! ----- Local
+ aster_logical :: near
+ real(kind=8) :: ecart
+! tolerances --- absolue et relative --- pour determiner si deux distances sont egales
+ real(kind=8), parameter :: atol = 1.e-12
+ real(kind=8), parameter :: rtol = 1.e-12
+! ------------------------------------------------------------------------------------------------
+!
+ projType = 0
+ ecart = -1.d0
+
+! ----- Premier ajustement : on positionne le point sur le bord, s'il est à une distance
+! ----- (normalisée) inférieure a atol du bord
+ if (abs(poinCoorPara(1)+1.d0) .le. atol) then
+ poinCoorPara(1) = -1.d0
+ end if
+ if (abs(poinCoorPara(1)-1.d0) .le. atol) then
+ poinCoorPara(1) = +1.d0
+ end if
+
+! ----- RABATTEMENT
+ if ((poinCoorPara(1) .lt. -1.d0) .or. (poinCoorPara(1) .gt. 1.d0)) then
+ ecart = abs(poinCoorPara(1))-1.d0
+ projType = 1
+ if (poinCoorPara(1) .lt. -1.d0) then
+ poinCoorPara(1) = -1.d0
+ else if (poinCoorPara(1) .gt. 1.d0) then
+ poinCoorPara(1) = 1.d0
+ end if
+ near = abs(ecart-projOutside) .le. (atol+projOutside*rtol)
+ if (ecart .gt. projOutside .and. .not. near) then
+ projType = 2
+ end if
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellPoinAdjustTria
+!
+! Adjust parametric coordinates to be inside cell when cell is triangle
+!
+! In projOutside : tolerance for projection outside cell
+! IO poinCoorPara : coordinates of point
+! Out projType : type of projection
+! 0 - No projection inside cell (point is inside)
+! 1 - Projection inside cell
+! 2 - No projection inside cell (to far away)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellPoinAdjustTria(projOutside, &
+ poinCoorPara, projType)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ real(kind=8), intent(in) :: projOutside
+ real(kind=8), intent(inout) :: poinCoorPara(2)
+ integer, intent(out) :: projType
+! ----- Local
+ integer :: izone
+ aster_logical :: near
+ real(kind=8) :: ecart, k1pk2, k2mk1, ksi1e, ksi2e
+! tolerances --- absolue et relative --- pour determiner si deux distances sont egales
+ real(kind=8), parameter :: atol = 1.e-12
+ real(kind=8), parameter :: rtol = 1.e-12
+! ------------------------------------------------------------------------------------------------
+!
+ projType = 0
+ ecart = -1.d0
+ k1pk2 = poinCoorPara(1)+poinCoorPara(2)
+ k2mk1 = poinCoorPara(2)-poinCoorPara(1)
+
+! ----- Premier ajustement : on positionne le point sur le bord, s'il est à une distance
+! ----- (normalisée) inférieure a atol du bord
+ if (abs(poinCoorPara(1)) .le. atol) then
+ poinCoorPara(1) = 0.d0
+ end if
+ if (abs(poinCoorPara(2)) .le. atol) then
+ poinCoorPara(2) = 0.d0
+ end if
+ if (abs(k1pk2-1.d0) .le. atol) then
+ k1pk2 = +1.d0
+ end if
+ if (abs(k2mk1+1.d0) .le. atol) then
+ k2mk1 = -1.d0
+ end if
+ if (abs(k2mk1-1.d0) .le. atol) then
+ k2mk1 = +1.d0
+ end if
+ if ((poinCoorPara(1) .ge. 0.d0) .and. (poinCoorPara(2) .ge. 0.d0) .and. &
+ (k1pk2 .le. 1.d0)) then
+ goto 99
+ end if
+
+! ----- SECTEUR CONCERNE
+ izone = 0
+ if (poinCoorPara(1) .lt. 0.d0) then
+ if (poinCoorPara(2) .lt. 0.d0) then
+ izone = 1
+ else if ((poinCoorPara(2) .ge. 0.d0) .and. (poinCoorPara(2) .le. 1.d0)) then
+ izone = 2
+ else if (poinCoorPara(2) .gt. 1.d0) then
+ izone = 3
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ end if
+ if (poinCoorPara(2) .lt. 0.d0) then
+ if (poinCoorPara(1) .lt. 0.d0) then
+ izone = 1
+ else if ((poinCoorPara(1) .ge. 0.d0) .and. (poinCoorPara(1) .le. 1.d0)) then
+ izone = 8
+ else if (poinCoorPara(1) .gt. 1.d0) then
+ izone = 7
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ end if
+ if (poinCoorPara(1) .ge. 0.d0) then
+ if (k2mk1 .gt. 1.d0) then
+ izone = 4
+ elseif ((k1pk2 .gt. 1.d0) .and. (k2mk1 .ge. -1.d0) &
+ .and. (k2mk1 .le. 1.d0)) then
+ izone = 5
+ ksi1e = 5.d-1*(1.d0+poinCoorPara(1)-poinCoorPara(2))
+ ksi2e = 5.d-1*(1.d0-poinCoorPara(1)+poinCoorPara(2))
+ else if ((poinCoorPara(2) .ge. 0.d0) .and. (k2mk1 .lt. -1.d0)) then
+ izone = 6
+ end if
+ end if
+
+! ----- CALCUL DE L'ECART
+ if (izone .eq. 1) then
+ ecart = sqrt(abs(poinCoorPara(1))*abs(poinCoorPara(1))+ &
+ abs(poinCoorPara(2))*abs(poinCoorPara(2)))
+ else if (izone .eq. 2) then
+ ecart = sqrt(abs(poinCoorPara(1))*abs(poinCoorPara(1)))
+ else if (izone .eq. 3 .or. izone .eq. 4) then
+ ecart = sqrt(abs(poinCoorPara(1))*abs(poinCoorPara(1))+ &
+ (poinCoorPara(2)-1.d0)*(poinCoorPara(2)-1.d0))
+ else if (izone .eq. 5) then
+ ecart = sqrt((poinCoorPara(1)-ksi1e)*(poinCoorPara(1)-ksi1e)+ &
+ (poinCoorPara(2)-ksi2e)*(poinCoorPara(2)-ksi2e))
+ else if (izone .eq. 6 .or. izone .eq. 7) then
+ ecart = sqrt(abs(poinCoorPara(2))*abs(poinCoorPara(2))+ &
+ (poinCoorPara(1)-1.d0)*(poinCoorPara(1)-1.d0))
+ else if (izone .eq. 8) then
+ ecart = sqrt(abs(poinCoorPara(2))*abs(poinCoorPara(2)))
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+! ----- RABATTEMENT
+ projType = 1
+ if (izone .eq. 1) then
+ poinCoorPara(1) = 0.d0
+ poinCoorPara(2) = 0.d0
+ else if (izone .eq. 2) then
+ poinCoorPara(1) = 0.d0
+ else if (izone .eq. 3 .or. izone .eq. 4) then
+ poinCoorPara(1) = 0.d0
+ poinCoorPara(2) = 1.d0
+ else if (izone .eq. 5) then
+ poinCoorPara(1) = ksi1e
+ poinCoorPara(2) = ksi2e
+ else if (izone .eq. 6 .or. izone .eq. 7) then
+ poinCoorPara(1) = 1.d0
+ poinCoorPara(2) = 0.d0
+ else if (izone .eq. 8) then
+ poinCoorPara(2) = 0.d0
+ end if
+
+ near = abs(ecart-projOutside) .le. (atol+projOutside*rtol)
+ if (ecart .gt. projOutside .and. .not. near) then
+ projType = 2
+ end if
+99 continue
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellPoinAdjustQuad
+!
+! Adjust parametric coordinates to be inside cell when cell is quadrangle
+!
+! In projOutside : tolerance for projection outside cell
+! IO poinCoorPara : coordinates of point
+! Out projType : type of projection
+! 0 - No projection inside cell (point is inside)
+! 1 - Projection inside cell
+! 2 - No projection inside cell (to far away)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellPoinAdjustQuad(projOutside, &
+ poinCoorPara, projType)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameter
+ real(kind=8), intent(in) :: projOutside
+ real(kind=8), intent(inout) :: poinCoorPara(2)
+ integer, intent(out) :: projType
+! ----- Local
+ integer :: izone
+ aster_logical :: near
+ real(kind=8) :: ecart, k1pk2, k2mk1
+! tolerances --- absolue et relative --- pour determiner si deux distances sont egales
+ real(kind=8), parameter :: atol = 1.e-12
+ real(kind=8), parameter :: rtol = 1.e-12
+! ------------------------------------------------------------------------------------------------
+!
+ projType = 0
+ ecart = -1.d0
+ k1pk2 = poinCoorPara(1)+poinCoorPara(2)
+ k2mk1 = poinCoorPara(2)-poinCoorPara(1)
+
+! ----- Premier ajustement : on positionne le point sur le bord, s'il est à une distance
+! ----- (normalisée) inférieure a atol du bord
+ if (abs(poinCoorPara(1)+1.d0) .le. atol) then
+ poinCoorPara(1) = -1.d0
+ end if
+ if (abs(poinCoorPara(1)-1.d0) .le. atol) then
+ poinCoorPara(1) = +1.d0
+ end if
+ if (abs(poinCoorPara(2)+1.d0) .le. atol) then
+ poinCoorPara(2) = -1.d0
+ end if
+ if (abs(poinCoorPara(2)-1.d0) .le. atol) then
+ poinCoorPara(2) = +1.d0
+ end if
+ if ((poinCoorPara(1) .ge. -1.d0) .and. (poinCoorPara(1) .le. 1.d0) .and. &
+ (poinCoorPara(2) .ge. -1.d0) .and. (poinCoorPara(2) .le. 1.d0)) then
+ goto 99
+ end if
+
+! ----- SECTEUR CONCERNE
+ izone = 0
+ if (poinCoorPara(1) .lt. -1.d0) then
+ if (poinCoorPara(2) .lt. -1.d0) then
+ izone = 1
+ else if ((poinCoorPara(2) .ge. -1.d0) .and. (poinCoorPara(2) .le. 1.d0)) then
+ izone = 2
+ else if (poinCoorPara(2) .gt. 1.d0) then
+ izone = 3
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ end if
+ if (poinCoorPara(1) .gt. 1.d0) then
+ if (poinCoorPara(2) .lt. -1.d0) then
+ izone = 7
+ else if ((poinCoorPara(2) .ge. -1.d0) .and. (poinCoorPara(2) .le. 1.d0)) then
+ izone = 6
+ else if (poinCoorPara(2) .gt. 1.d0) then
+ izone = 5
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ end if
+ if ((poinCoorPara(1) .ge. -1.d0) .and. (poinCoorPara(1) .le. 1.d0)) then
+ if (poinCoorPara(2) .lt. -1.d0) then
+ izone = 8
+ else if (poinCoorPara(2) .gt. 1.d0) then
+ izone = 4
+ end if
+ end if
+
+! ----- CALCUL DE L'ECART
+ if (izone .eq. 1) then
+ ecart = sqrt((abs(poinCoorPara(1))-1.d0)*(abs(poinCoorPara(1))-1.d0)+ &
+ (abs(poinCoorPara(2))-1.d0)*(abs(poinCoorPara(2))-1.d0))
+ else if (izone .eq. 2) then
+ ecart = sqrt((abs(poinCoorPara(1))-1.d0)*(abs(poinCoorPara(1))-1.d0))
+ else if (izone .eq. 3) then
+ ecart = sqrt((abs(poinCoorPara(1))-1.d0)*(abs(poinCoorPara(1))-1.d0)+ &
+ (abs(poinCoorPara(2))-1.d0)*(abs(poinCoorPara(2))-1.d0))
+ else if (izone .eq. 4) then
+ ecart = sqrt((abs(poinCoorPara(2))-1.d0)*(abs(poinCoorPara(2))-1.d0))
+ else if (izone .eq. 5) then
+ ecart = sqrt((abs(poinCoorPara(1))-1.d0)*(abs(poinCoorPara(1))-1.d0)+ &
+ (abs(poinCoorPara(2))-1.d0)*(abs(poinCoorPara(2))-1.d0))
+ else if (izone .eq. 6) then
+ ecart = sqrt((abs(poinCoorPara(1))-1.d0)*(abs(poinCoorPara(1))-1.d0))
+ else if (izone .eq. 7) then
+ ecart = sqrt((abs(poinCoorPara(1))-1.d0)*(abs(poinCoorPara(1))-1.d0)+ &
+ (abs(poinCoorPara(2))-1.d0)*(abs(poinCoorPara(2))-1.d0))
+ else if (izone .eq. 8) then
+ ecart = sqrt((abs(poinCoorPara(2))-1.d0)*(abs(poinCoorPara(2))-1.d0))
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+! ----- RABATTEMENT
+ projType = 1
+ if (izone .eq. 1) then
+ poinCoorPara(1) = -1.d0
+ poinCoorPara(2) = -1.d0
+ else if (izone .eq. 2) then
+ poinCoorPara(1) = -1.d0
+ else if (izone .eq. 3) then
+ poinCoorPara(1) = -1.d0
+ poinCoorPara(2) = 1.d0
+ else if (izone .eq. 4) then
+ poinCoorPara(2) = 1.d0
+ else if (izone .eq. 5) then
+ poinCoorPara(1) = 1.d0
+ poinCoorPara(2) = 1.d0
+ else if (izone .eq. 6) then
+ poinCoorPara(1) = 1.d0
+ else if (izone .eq. 7) then
+ poinCoorPara(1) = 1.d0
+ poinCoorPara(2) = -1.d0
+ else if (izone .eq. 8) then
+ poinCoorPara(2) = -1.d0
+ end if
+
+ near = abs(ecart-projOutside) .le. (atol+projOutside*rtol)
+ if (ecart .gt. projOutside .and. .not. near) then
+ projType = 2
+ end if
+!
+99 continue
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+!
+end module
diff --git a/bibfor/mesh/mesh_operators_type.F90 b/bibfor/mesh/mesh_operators_type.F90
index ba994f8dfbb..affe4e29115 100644
--- a/bibfor/mesh/mesh_operators_type.F90
+++ b/bibfor/mesh/mesh_operators_type.F90
@@ -1,5 +1,5 @@
! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
! This file is part of code_aster.
!
! code_aster is free software: you can redistribute it and/or modify
@@ -15,45 +15,51 @@
! You should have received a copy of the GNU General Public License
! along with code_aster. If not, see .
! --------------------------------------------------------------------
-! person_in_charge: mickael.abbas at edf.fr
!
+! ==================================================================================================
+!
+! Module for types in MODI_MAILLAGE command
+!
+! ==================================================================================================
module mesh_operators_type
- !
+! ==================================================================================================
use Behaviour_type
- !
+! ==================================================================================================
implicit none
- !
+! ==================================================================================================
+ private
#include "asterf_types.h"
-
! ==================================================================================================
-!
! Global variables
-!
! ==================================================================================================
-
+! - Non
! ==================================================================================================
-!
-! Derivated types - Parameters from MODI_MAILLAGE command
-!
+! Define types
! ==================================================================================================
-
+! --------------------------------------------------------------------------------------------------
+! For MODI_MAILLAGE/ ORIE_NORM_COQUE operator
+! --------------------------------------------------------------------------------------------------
type MESH_OPER_ORIE_SHELL
aster_logical :: orieByVect = ASTER_FALSE
real(kind=8) :: orieVect(3) = 0.d0
-
integer :: nbGroupCell = 0
character(len=24), pointer :: listOfGroupOfCell(:) => null()
-
integer :: nodeNume = 0
-
end type MESH_OPER_ORIE_SHELL
-
+! --------------------------------------------------------------------------------------------------
+! For MODI_MAILLAGE/ORIE_* operators
+! --------------------------------------------------------------------------------------------------
type MESH_OPER_MODI_PARA
integer :: orieShell = 0
type(MESH_OPER_ORIE_SHELL), pointer :: meshOperOrieShell(:) => null()
integer :: orieSkin = 0
integer :: orieLine = 0
end type MESH_OPER_MODI_PARA
-
+!===================================================================================================
+!===================================================================================================
+ public :: MESH_OPER_ORIE_SHELL, MESH_OPER_MODI_PARA
+contains
+!===================================================================================================
+!===================================================================================================
!
end module mesh_operators_type
diff --git a/bibfor/mesh/mesh_pairing_module.F90 b/bibfor/mesh/mesh_pairing_module.F90
new file mode 100644
index 00000000000..6274c0d3c78
--- /dev/null
+++ b/bibfor/mesh/mesh_pairing_module.F90
@@ -0,0 +1,2847 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+! aslint: disable=W1306
+!
+! ==================================================================================================
+!
+! Module for pairing meshes
+!
+! ==================================================================================================
+!
+module MeshPairing_module
+! ==================================================================================================
+ use mesh_type
+ use mesh_cell_module
+! ==================================================================================================
+ implicit none
+! ==================================================================================================
+ public :: fastPair, robustPair, pairDeallocate, pairAllocate
+ public :: inteCellArea, intePoinCoor, quadPoinCoor
+ public :: getPairJV, getInteJV, pairAdd
+ private :: pairGetStartCells, getClosestNodesFromCell, getCellsFromNode
+ private :: cellInteProj, cellProjOnCell, nodeProjOnCell
+ private :: poinProjOnCell, poinProjByVect, poinIsInsideOtherCell
+ private :: inteCellChck, addPoinInte2D, addPoinInte3D, addPoinOnEdge
+ private :: inteCellSegm, intePoinSort, intePoinInCell
+ private :: isFatalError
+! ==================================================================================================
+ private
+#include "asterc/r8gaem.h"
+#include "asterc/r8prem.h"
+#include "asterf_types.h"
+#include "asterfort/as_allocate.h"
+#include "asterfort/as_deallocate.h"
+#include "asterfort/assert.h"
+#include "asterfort/elrfdf.h"
+#include "asterfort/elrfvf.h"
+#include "asterfort/jeexin.h"
+#include "asterfort/jelira.h"
+#include "asterfort/jeveuo.h"
+#include "asterfort/jexatr.h"
+#include "asterfort/mesh_pairing_type.h"
+#include "asterfort/ordr8.h"
+#include "asterfort/utmess.h"
+#include "jeveux.h"
+#include "MeshTypes_type.h"
+! ==================================================================================================
+! ==================================================================================================
+! Global variables
+! ==================================================================================================
+! - Index of next nodes for segment, triangle and quadrangle
+ integer, parameter :: nodeNextSEG(2) = (/2, 1/)
+ integer, parameter :: nodeNextTRIA(3) = (/2, 3, 1/)
+ integer, parameter :: nodeNextQUAD(4) = (/2, 3, 4, 1/)
+! - Index of previous nodes for triangle and quadrangle
+ integer, parameter :: nodePrevTRIA(3) = (/3, 1, 2/)
+ integer, parameter :: nodePrevQUAD(4) = (/4, 1, 2, 3/)
+! ==================================================================================================
+! Type for pairing
+! ==================================================================================================
+ type MESH_PAIRING
+! ----- Dimension of space (2 or 3)
+ integer :: spaceDime = 0
+! ----- Flag for debug (text)
+ aster_logical :: debug = ASTER_FALSE
+! ----- Main tolerance for pairing
+ real(kind=8) :: pairTole = 0.d0
+! ----- Tolerance for extension of cell
+ real(kind=8) :: distRatio = 0.d0
+! ----- Number of pairs
+ integer :: nbPair = 0
+! ----- Pointer to pairs
+ integer, pointer :: pair(:) => null()
+! ----- Pointer to list of intersection points
+ integer, pointer :: nbPoinInte(:) => null()
+ real(kind=8), pointer :: poinInte(:) => null()
+ end type MESH_PAIRING
+! ==================================================================================================
+! Type for parameters of projection algorithm
+! ==================================================================================================
+ type MESH_PROJ_PARA
+! ----- Parameters for algorithm
+ aster_logical :: debug = ASTER_FALSE
+ integer :: newtIterMaxi = 0
+ real(kind=8) :: newtTole = 0.d0
+! ----- Coordinate of point to project (in global frame)
+ real(kind=8) :: coorPoinGlob(3) = 0.d0
+! ----- Dimension of space (2 or 3)
+ integer :: spaceDime = 0
+! ----- Vector to project
+ real(kind=8):: projVect(3) = 0.d0
+! ----- Coordinate of point after projection (in cell parametric space)
+ real(kind=8) :: coorProjPara(2) = 0.d0
+! ----- Tangents at projection of point
+ real(kind=8) :: tau1(3) = 0.d0, tau2(3) = 0.d0
+! ----- Return code
+ integer:: errorCode = 0
+ end type MESH_PROJ_PARA
+! ==================================================================================================
+ public :: MESH_PAIRING, nodeNextTRIA, nodeNextQUAD, nodePrevTRIA, nodePrevQUAD
+! ==================================================================================================
+contains
+! --------------------------------------------------------------------------------------------------
+!
+! fastPair
+!
+! Fast pairing on zone
+!
+! In mesh : mesh
+! In newgeo : updated coordinates of nodes
+! In mastConxInvName : name of object for inverse connectivity of master cells on current zone
+! In mastNeighName : name of object for neighbours of master cells
+! In slavNeighName : name of object for neighbours of slave cells
+! In nbCellSlav : number of slave cells
+! In nbCellMast : number of master cells
+! In nbNodeMast : number of master nodes
+! In listCellSlav : list of slave cells
+! In listCellMast : list of master cells
+! In listNodeMast : list of master nodes
+! In meshPairing : main datastructure for pairing
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine fastPair(mesh, newgeo, mastConxInvName, &
+ mastNeighName, slavNeighName, &
+ nbCellSlav, nbCellMast, nbNodeMast, &
+ listCellSlav, listCellMast, listNodeMast, &
+ meshPairing)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ character(len=8), intent(in) :: mesh
+ character(len=24), intent(in) :: newgeo, mastConxInvName
+ character(len=24), intent(in) :: mastNeighName, slavNeighName
+ integer, intent(in) :: nbCellSlav, nbCellMast
+ integer, intent(in) :: listCellMast(nbCellMast), listCellSlav(nbCellSlav)
+ integer, intent(in) :: nbNodeMast
+ integer, intent(in) :: listNodeMast(nbNodeMast)
+ type(MESH_PAIRING), intent(inout) :: meshPairing
+! ----- Local
+ aster_logical :: pair_exist, isFatal, l_recup
+ integer :: nbSlavStart, nbMastStart
+ integer, pointer :: cellSlavStart(:) => null()
+ integer, pointer :: cellMastStart(:) => null()
+ integer, pointer :: cellMastFlag(:) => null()
+ integer, pointer :: cellSlavFlag(:) => null(), cellMastPaired(:) => null()
+ integer :: slavIndxMini, slavIndxMaxi
+ integer :: mastIndxMini, mastIndxMaxi
+ integer :: iCell, iMastNeigh, iSlavNeigh
+ real(kind=8), pointer :: nodeCoor(:) => null()
+ integer, pointer :: meshTypeGeom(:) => null()
+ integer, pointer :: meshConx(:) => null(), meshConxCumu(:) => null()
+ integer, pointer :: mastConxInv(:) => null(), mastConxInvCumu(:) => null()
+ type(CELL_GEOM) :: cellSlav, cellMast
+ type(CELL_GEOM) :: cellSlavLine, cellMastLine
+ integer :: nbSlavNeigh, nbMastPaired, inteNeigh(MAX_NB_NEIGH), nbMastNeigh
+ integer :: cellNeigh(MAX_NB_NEIGH), iret
+ real(kind=8) :: inteArea
+ integer :: mastFindIndx, cellMastNume, cellMastIndx, cellSlavIndx, cellSlavNume
+ integer :: nbPoinInte
+ real(kind=8) :: poinInte(2, MAX_NB_INTE), poinInteReal(3, MAX_NB_INTE)
+ integer :: cellNeighNume, cellNeighIndx
+ integer, pointer :: meshMastNeigh(:) => null(), meshSlavNeigh(:) => null()
+! ------------------------------------------------------------------------------------------------
+!
+ pair_exist = ASTER_TRUE
+ inteNeigh = 0
+ cellNeigh = 0
+ mastIndxMini = minval(listCellMast)
+ mastIndxMaxi = maxval(listCellMast)
+ slavIndxMaxi = maxval(listCellSlav)
+ slavIndxMini = minval(listCellSlav)
+
+! ----- Management of debug
+ if (meshPairing%debug) then
+ write (6, *) "================"
+ write (6, *) "= Fast pairing ="
+ write (6, *) "================"
+ write (6, *) " "
+ end if
+
+! ----- Access to updated geometry
+ call jeveuo(newgeo(1:19)//'.VALE', 'L', vr=nodeCoor)
+
+! ----- Access to mesh
+ call jeveuo(mesh(1:8)//'.TYPMAIL', 'L', vi=meshTypeGeom)
+ call jeveuo(mesh(1:8)//'.CONNEX', 'L', vi=meshConx)
+ call jeveuo(jexatr(mesh(1:8)//'.CONNEX', 'LONCUM'), 'L', vi=meshConxCumu)
+ call jeveuo(mastConxInvName, 'L', vi=mastConxInv)
+ call jeveuo(jexatr(mastConxInvName, 'LONCUM'), 'L', vi=mastConxInvCumu)
+ call jeveuo(mastNeighName, 'L', vi=meshMastNeigh)
+ call jeveuo(slavNeighName, 'L', vi=meshSlavNeigh)
+
+! ----- Protection
+ if (nbCellSlav .eq. 0 .or. nbCellMast .eq. 0) then
+ call utmess('F', 'MESH4_1')
+ end if
+
+! ----- List of starting cells
+ AS_ALLOCATE(vi=cellSlavStart, size=nbCellSlav)
+ AS_ALLOCATE(vi=cellMastStart, size=nbCellMast)
+
+! ----- Flag for slave cell usage status
+! 0 - Never used
+! 1 - Used as starting point
+! 2 - Used
+ AS_ALLOCATE(vi=cellSlavFlag, size=slavIndxMaxi+1-slavIndxMini)
+
+! ----- Flag for master cell usage status
+! 0 - Never used
+! 1 - Used as starting point
+ AS_ALLOCATE(vi=cellMastFlag, size=mastIndxMaxi+1-mastIndxMini)
+
+! ----- Master elements paired with the current slave cell (number of master elements: nbMastPaired)
+ AS_ALLOCATE(vi=cellMastPaired, size=nbCellMast)
+
+! ----- While loop on the existence of a pair slave-master
+ do while (pair_exist)
+ if (meshPairing%debug) then
+ WRITE (6, *) "Get cells for starting search"
+ WRITE (6, *) "============================="
+ end if
+! --------- Get initial start cells
+ call pairGetStartCells(meshPairing, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ mastConxInv, mastConxInvCumu, &
+ nbCellSlav, listCellSlav, cellSlavFlag, &
+ nbCellMast, listCellMast, &
+ nbNodeMast, listNodeMast, &
+ nbMastStart, cellMastStart, &
+ nbSlavStart, cellSlavStart)
+ ASSERT(nbMastStart .le. 1)
+ ASSERT(nbSlavStart .le. 1)
+ if (meshPairing%debug) then
+ if (nbSlavStart .eq. 1 .and. nbMastStart .eq. 1) then
+ WRITE (6, *) " New starting point (M/S): ", cellMastStart(1), cellSlavStart(1)
+ else
+ WRITE (6, *) " Not new starting point (M/S)"
+ end if
+ end if
+
+! --------- No more slave cell
+ if (nbSlavStart == 0) then
+ pair_exist = ASTER_FALSE
+ end if
+
+ do while (nbSlavStart > 0)
+! ------------- Get slave element
+ cellSlavNume = cellSlavStart(1)
+ cellSlavIndx = cellSlavNume+1-slavIndxMini
+
+! ------------- Shift list of starting slave cells
+ do iCell = 1, nbSlavStart-1
+ cellSlavStart(iCell) = cellSlavStart(iCell+1)
+ end do
+ nbSlavStart = nbSlavStart-1
+
+! ------------- Create slave cell
+ call cellCreate(cellSlavNume, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ cellSlav, cellSlavLine)
+
+ if (meshPairing%debug) then
+ write (6, *) "Current slave element : ", cellSlavNume
+ write (6, *) " Coordinates (global frame): ", &
+ cellSlav%coorNodeGlob(1:meshPairing%spaceDime, 1:cellSlav%nbNode)
+ end if
+
+! ------------- Get number of neighbours
+ nbSlavNeigh = cellSlav%nbNeigh
+ ASSERT(nbSlavNeigh .le. MAX_NB_NEIGH)
+ if (meshPairing%debug) then
+ write (6, *) "Potential number of neighbours: ", nbSlavNeigh
+ do iSlavNeigh = 1, nbSlavNeigh
+ cellNeighNume = meshSlavNeigh(4*(cellSlavIndx-1)+iSlavNeigh)
+ if (cellNeighNume .eq. 0) then
+ write (6, *) "Neighbour (", iSlavNeigh, "): "
+ else
+ write (6, *) "Neighbour (", iSlavNeigh, "): ", cellNeighNume
+ end if
+ end do
+ end if
+ cellNeigh = 0
+
+! ------------- Get master element to start (don't use this starting cell for pairing)
+ cellMastNume = cellMastStart(1)
+ mastFindIndx = cellMastNume+1-mastIndxMini
+ cellMastFlag(mastFindIndx) = 1
+ if (meshPairing%debug) then
+ WRITE (6, *) "Avant décalage"
+ WRITE (6, *) " => ", nbMastStart, cellMastStart(1:nbMastStart)
+ end if
+
+! ------------- Delete cell in the list of master element start
+ do iCell = 1, nbMastStart-1
+ cellMastStart(iCell) = cellMastStart(iCell+1)
+ end do
+ nbMastStart = nbMastStart-1
+ if (meshPairing%debug) then
+ WRITE (6, *) "Après décalage"
+ WRITE (6, *) " => ", nbMastStart, cellMastStart(1:nbMastStart)
+ end if
+
+! ------------- Management of list of master elements: first element to seek
+ cellMastPaired(1) = cellMastNume
+ nbMastPaired = 1
+ if (meshPairing%debug) then
+ write (6, *) "Master cell to start: ", cellMastNume
+ end if
+
+! ------------- Initialization list of pairs
+ l_recup = ASTER_TRUE
+
+! ------------- Loop on master elements => Look for the master elements
+ do while (nbMastPaired > 0)
+ inteArea = 0.d0
+ nbPoinInte = 0
+ poinInte = 0.d0
+ poinInteReal = 0.d0
+
+! ----------------- Get master element
+ cellMastNume = cellMastPaired(1)
+ cellMastIndx = cellMastNume+1-mastIndxMini
+
+! ----------------- Shift list of master element to pair
+ do iCell = 1, nbMastPaired-1
+ cellMastPaired(iCell) = cellMastPaired(iCell+1)
+ end do
+ nbMastPaired = nbMastPaired-1
+
+! ----------------- Create master cell
+ call cellCreate(cellMastNume, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ cellMast, cellMastLine)
+ if (meshPairing%debug) then
+ write (6, *) "Current master element: ", cellMastNume
+ write (6, *) " Coordinates (global frame): ", &
+ cellMast%coorNodeGlob(1:meshPairing%spaceDime, 1:cellMast%nbNode)
+ end if
+
+! ----------------- Get number of neighbours
+ nbMastNeigh = cellMast%nbNeigh
+ ASSERT(nbMastNeigh .le. MAX_NB_NEIGH)
+ if (meshPairing%debug) then
+ write (6, *) "Potential number of neighbours: ", nbMastNeigh
+ end if
+
+! ----------------- Compute intersection of the two cells
+ if (meshPairing%debug) then
+ WRITE (6, *) "Compute intersection and projection in master space"
+ end if
+ call cellInteProj(meshPairing, &
+ cellSlav, cellSlavLine, cellMastLine, &
+ iret, &
+ nbPoinInte, poinInte, &
+ inteArea, inteNeigh)
+ isFatal = isFatalError(iret)
+ if (.not. isFatal .and. iret .ne. ERR_PAIR_NONE) then
+ call utmess('A', 'MESH4_3')
+ inteArea = 0.d0
+ nbPoinInte = 0
+ end if
+ ASSERT(nbPoinInte .le. MAX_NB_INTE)
+ if (meshPairing%debug) then
+ WRITE (6, *) "Intersection area: ", inteArea
+ end if
+
+! ----------------- Add pair
+ if (inteArea > meshPairing%pairTole .and. iret == ERR_PAIR_NONE) then
+
+! --------------------- Debug
+ if (meshPairing%debug) then
+! ------------------------- Compute coordinates in global space for intersection points
+ call intePoinCoor(cellSlav, nbPoinInte, poinInte, poinInteReal)
+ WRITE (6, *) "Add pair: ", meshPairing%nbPair+1, &
+ "(", cellSlavNume, "-", cellMastNume, ")"
+ WRITE (6, *) "Nb points integrations : ", &
+ nbPoinInte
+ WRITE (6, *) "Coor. points integrations (parametric): ", &
+ poinInte(:, 1:nbPoinInte)
+ WRITE (6, *) "Coef. points integrations (global) : ", &
+ poinInteReal(:, 1:nbPoinInte)
+ WRITE (6, *) "Area of intersection : ", &
+ inteArea
+ end if
+! --------------------- Add pair
+ call pairAdd(cellSlavNume, cellMastNume, &
+ nbPoinInte, poinInte, &
+ meshPairing)
+ end if
+
+! ----------------- Find neighbour of current master element
+ if (inteArea > meshPairing%pairTole .or. l_recup) then
+! --------------------- Prepare next master element
+ if (meshPairing%debug) then
+ WRITE (6, *) "Prepare next master element"
+ end if
+ do iMastNeigh = 1, nbMastNeigh
+ cellNeighNume = meshMastNeigh(MAX_NB_NEIGH*(cellMastIndx-1)+iMastNeigh)
+ cellNeighIndx = cellNeighNume+1-mastIndxMini
+ if (cellNeighNume .ne. 0 .and. &
+ cellMastFlag(cellNeighIndx) .ne. 1) then
+ nbMastPaired = nbMastPaired+1
+ cellMastPaired(nbMastPaired) = cellNeighNume
+ cellMastFlag(cellNeighIndx) = 1
+ if (meshPairing%debug) then
+ WRITE (6, *) " => added: ", nbMastPaired, &
+ cellMastPaired(nbMastPaired)
+ end if
+ end if
+ end do
+
+! --------------------- Prepare next slave element
+ if (meshPairing%debug) then
+ WRITE (6, *) "Prepare next slave element"
+ end if
+ do iSlavNeigh = 1, nbSlavNeigh
+ cellNeighNume = meshSlavNeigh(MAX_NB_NEIGH*(cellSlavIndx-1)+iSlavNeigh)
+ cellNeighIndx = cellNeighNume+1-slavIndxMini
+ if (meshPairing%debug) then
+ WRITE (6, *) " < Index:", iSlavNeigh
+ WRITE (6, *) " < cellNeighNume:", cellNeighNume
+ WRITE (6, *) " < cellNeighIndx: ", cellNeighIndx
+ WRITE (6, *) " < cellSlavFlag: ", cellSlavFlag(cellNeighIndx)
+ WRITE (6, *) " < inteNeigh: ", inteNeigh(iSlavNeigh)
+ end if
+ if (cellNeighNume .ne. 0 .and. &
+ cellSlavFlag(cellNeighIndx) .ne. 1 .and. &
+ inteNeigh(iSlavNeigh) == 1) then
+ cellNeigh(iSlavNeigh) = cellMastNume
+ if (meshPairing%debug) then
+ WRITE (6, *) " => added: ", cellMastNume
+ end if
+ end if
+ end do
+ l_recup = ASTER_FALSE
+ end if
+ end do
+
+! ------------- Next elements
+ if (meshPairing%debug) then
+ WRITE (6, *) "Prepare next elements - Nb: ", nbSlavNeigh
+ end if
+ do iSlavNeigh = 1, nbSlavNeigh
+ cellNeighNume = meshSlavNeigh(MAX_NB_NEIGH*(cellSlavIndx-1)+iSlavNeigh)
+ cellNeighIndx = cellNeighNume+1-slavIndxMini
+ if (meshPairing%debug) then
+ write (*, *) 'Next elements - Current: ', iSlavNeigh, cellNeighNume, &
+ cellNeigh(iSlavNeigh), cellSlavFlag(cellNeighIndx)
+ end if
+ if (cellNeighNume .ne. 0 .and. &
+ cellNeigh(iSlavNeigh) .ne. 0 .and. &
+ cellSlavFlag(cellNeighIndx) .ne. 1) then
+ nbSlavStart = nbSlavStart+1
+ cellSlavStart(nbSlavStart) = cellNeighNume
+ cellSlavFlag(cellNeighIndx) = 1
+ nbMastStart = nbMastStart+1
+ cellMastStart(nbMastStart) = cellNeigh(iSlavNeigh)
+ end if
+ end do
+
+! ------------- All master cells are candidates for pairing
+ cellMastFlag(1:mastIndxMaxi+1-mastIndxMini) = 0
+ end do
+ !pair_exist = ASTER_FALSE
+ end do
+
+! ----- Clean memory
+ AS_DEALLOCATE(vi=cellSlavStart)
+ AS_DEALLOCATE(vi=cellMastStart)
+ AS_DEALLOCATE(vi=cellSlavFlag)
+ AS_DEALLOCATE(vi=cellMastFlag)
+ AS_DEALLOCATE(vi=cellMastPaired)
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! nodeProjOnCell
+!
+! Project nodes of cell (origin) on another cell (target) in target parametric space using
+! raytracing
+!
+! In meshPairing : main datastructure for pairing
+! In cellOrig : geometric properties of cell to project
+! In cellOrigLine : geometric properties of cell to project (linearized)
+! In cellTargLine : geometric properties of cell where to project (linearized)
+! IO cellProj : geometric properties of projected cell
+! Out nbNodeProj : number of projected nodes
+! Out iret : return code error
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine nodeProjOnCell(meshPairing, &
+ cellOrig, cellOrigLine, cellTargLine, &
+ cellProj, nbNodeProj, iret)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ type(CELL_GEOM), intent(in) :: cellOrig, cellOrigLine, cellTargLine
+ type(CELL_GEOM), intent(inout) :: cellProj
+ integer, intent(out) :: nbNodeProj, iret
+! ----- Local
+ integer :: iNode, nbNode
+ real(kind=8) :: coorNodeGlob(3), coorNodePara(3), projNodePara(3), projNodeGlob(3)
+ type(CELL_SKIN_BASE) :: base
+ aster_logical :: errorProj
+! ------------------------------------------------------------------------------------------------
+!
+ iret = ERR_PAIR_NONE
+ nbNodeProj = 0
+ ASSERT(cellOrigLine%isLinear)
+ ASSERT(cellTargLine%isLinear)
+
+ if (meshPairing%debug) then
+ WRITE (6, *) " Project nodes of cell on another cell using raytracing"
+ WRITE (6, *) " ======================================================"
+ end if
+
+! ----- Projected cell: same type as original one
+ call cellCopyType(cellOrigLine, cellProj)
+ cellProj%coorNodePara = 0.d0
+ cellProj%coorNodeGlob = 0.d0
+
+! ----- Project only vertices of original cell (linearized cell)
+ nbNode = cellOrigLine%nbNode
+ nbNodeProj = nbNode
+ if (meshPairing%debug) then
+ WRITE (6, *) " Number of nodes on original cell: ", nbNode
+ end if
+ do iNode = 1, nbNode
+ if (meshPairing%debug) then
+ WRITE (6, *) " Current node: ", iNode
+ end if
+
+! --------- Get coordinates of current node (real space and parametric space)
+ coorNodeGlob = cellOrigLine%coorNodeGlob(:, iNode)
+ coorNodePara = cellOrigLine%coorNodePara(:, iNode)
+ if (meshPairing%debug) then
+ WRITE (6, *) " Coordinate of node to project (local frame): ", &
+ coorNodePara
+ WRITE (6, *) " Coordinate of node to project (global frame): ", &
+ coorNodeGlob
+ end if
+
+! --------- Compute base on this node (outward normal)
+ call cellCompBaseAtPoint(cellOrig, meshPairing%spaceDime, coorNodePara, base)
+ if (meshPairing%debug) then
+ WRITE (6, *) " Normal at node to project: ", base%norm
+ end if
+
+! --------- Project node on target cell
+ call poinProjOnCell(meshPairing%spaceDime, meshPairing%pairTole, &
+ coorNodeGlob, base%norm, &
+ cellTargLine, &
+ projNodePara, errorProj)
+
+! --------- Careful ! projNodePara can be outside of reference frame !
+
+! --------- Failure
+ if (errorProj) then
+ if (meshPairing%debug) then
+ WRITE (6, *) " Failure of projection of node"
+ end if
+ nbNodeProj = 0
+ cellProj%coorNodePara = 0.d0
+ cellProj%coorNodeGlob = 0.d0
+ iret = ERR_PAIR_PROJ
+ exit
+ end if
+
+! --------- Transform coordinates of the projection in global space
+ call cellPoinParaToGlob(cellTargLine, projNodePara, projNodeGlob)
+ if (meshPairing%debug) then
+ WRITE (6, *) " Success of projection of node"
+ WRITE (6, *) " Coordinates of the projection of the node (local frame): ", &
+ projNodePara(1:2)
+ WRITE (6, *) " Coordinates of the projection of the node(global frame): ", &
+ projNodeGlob
+ end if
+
+! --------- Save projection of node for this cell
+ cellProj%coorNodePara(1:2, iNode) = projNodePara(1:2)
+ cellProj%coorNodeGlob(:, iNode) = projNodeGlob
+
+ end do
+
+! ----- Update parameters for projected cell
+ call cellCompBary(cellProj)
+ call cellCompDiam(cellProj)
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! poinProjOnCell
+!
+! Project a point on cell - Cell is linear
+!
+! In coorPoinGlob : coordinates of point in global frame
+! In projTole : tolerance for projection
+! In normPoint : normal at point
+! In cellGeomTarget : cell where to project
+! Out coorProjPara : coordinates of point in reference frame of target cell
+! Out errorProj : error code
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine poinProjOnCell(spaceDime, projTole, &
+ coorPoinGlob, normPoint, &
+ cellGeomTarget, &
+ coorProjPara, errorProj)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ integer, intent(in) :: spaceDime
+ real(kind=8), intent(in) :: projTole
+ real(kind=8), intent(in) :: coorPoinGlob(3), normPoint(3)
+ type(CELL_GEOM), intent(in) :: cellGeomTarget
+ real(kind=8), intent(out) :: coorProjPara(3)
+ aster_logical, intent(out) :: errorProj
+! ----- Local
+ aster_logical, parameter :: debug = ASTER_FALSE
+ type(MESH_PROJ_PARA) :: projPara
+! ------------------------------------------------------------------------------------------------
+!
+ coorProjPara = 0.d0
+ errorProj = ASTER_FALSE
+ ASSERT(cellGeomTarget%isLinear)
+ ASSERT(cellGeomTarget%isSkin)
+
+! ----- Set parameters of Newton algorithm for projection
+ projPara%debug = debug
+ projPara%newtIterMaxi = 75
+ projPara%newtTole = projTole
+
+! ----- Prepare object for projection on target cell
+ projPara%spaceDime = spaceDime
+ projPara%coorPoinGlob = coorPoinGlob
+ projPara%projVect = normPoint
+
+! ----- Projection by given vector
+ call poinProjByVect(projPara, cellGeomTarget)
+
+! ----- Copy to output results
+ coorProjPara(1:2) = projPara%coorProjPara
+ errorProj = projPara%errorCode .ne. 0
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! poinProjByVect
+!
+! Projection of a point on _skin_ cell by given vector
+!
+! IO projPara : parameters of projection
+! In cellTarget : target cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine poinProjByVect(projPara, cellTarget)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PROJ_PARA), intent(inout) :: projPara
+ type(CELL_GEOM), intent(in) :: cellTarget
+! ----- Local
+ real(kind=8), parameter :: zero = 0.d0, one = 1.d0
+ integer :: iNode, iDime, spaceDime
+ real(kind=8) :: shapeFunc(MT_NNOMAX3D), dShapeFunc(3, MT_NNOMAX3D)
+ real(kind=8) :: vect_posi(3), dist
+ real(kind=8) :: residu(3), matrix(3, 3), det
+ real(kind=8) :: dksi(2), dbeta, beta
+ integer :: iterNewt
+ real(kind=8) :: toleAbso, toleRela, toleNewt
+ real(kind=8) :: distMini, ksiMini(2), betaMini
+ real(kind=8) :: refe, test
+! ------------------------------------------------------------------------------------------------
+!
+ ASSERT(cellTarget%isSkin)
+ spaceDime = projPara%spaceDime
+ projPara%errorCode = 0
+ projPara%coorProjPara = zero
+ beta = one
+ iterNewt = 0
+ toleAbso = projPara%newtTole/100.d0
+ toleRela = projPara%newtTole
+ distMini = r8gaem()
+
+! ----- Newton loop
+20 continue
+ vect_posi = zero
+ projPara%tau1 = zero
+ projPara%tau2 = zero
+ matrix = zero
+ residu = zero
+ dksi = zero
+ dbeta = zero
+
+! ----- Get shape functions and derivated shape functions
+ call elrfvf(cellTarget%cellCode, projPara%coorProjPara, shapeFunc)
+ call elrfdf(cellTarget%cellCode, projPara%coorProjPara, dShapeFunc)
+
+! ----- Position vector of current point
+ do iDime = 1, 3
+ do iNode = 1, cellTarget%nbNode
+ vect_posi(iDime) = &
+ cellTarget%coorNodeGlob(iDime, iNode)*shapeFunc(iNode)+vect_posi(iDime)
+ end do
+ end do
+
+! ----- Compute local base
+ call cellCompTang(cellTarget, spaceDime, dShapeFunc, projPara%tau1, projPara%tau2)
+
+! ----- Quantity to minimize
+ do iDime = 1, 3
+ vect_posi(iDime) = projPara%coorPoinGlob(iDime)-vect_posi(iDime)
+ end do
+ dist = sqrt(vect_posi(1)*vect_posi(1)+vect_posi(2)*vect_posi(2)+vect_posi(3)*vect_posi(3))
+
+! ----- Newton residual
+ do iDime = 1, 3
+ residu(iDime) = vect_posi(iDime)-beta*projPara%projVect(iDime)
+ end do
+
+! ----- Tangent matrix (Newton)
+ do iDime = 1, 3
+ matrix(iDime, 1) = projPara%tau1(iDime)
+ if (spaceDime .eq. 2) then
+ matrix(iDime, 2) = projPara%projVect(iDime)
+ elseif (spaceDime .eq. 3) then
+ matrix(iDime, 2) = projPara%tau2(iDime)
+ matrix(iDime, 3) = projPara%projVect(iDime)
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ end do
+
+! ----- System determinant
+ if (spaceDime .eq. 2) then
+ det = matrix(1, 1)*matrix(2, 2)-matrix(1, 2)*matrix(2, 1)
+ else if (spaceDime .eq. 3) then
+ det = matrix(1, 1)*(matrix(2, 2)*matrix(3, 3)-matrix(3, 2)*matrix(2, 3))- &
+ matrix(2, 1)*(matrix(1, 2)*matrix(3, 3)-matrix(3, 2)*matrix(1, 3))+ &
+ matrix(3, 1)*(matrix(1, 2)*matrix(2, 3)-matrix(2, 2)*matrix(1, 3))
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+!
+ if (abs(det) .le. r8prem()) then
+ projPara%errorCode = 1
+ goto 99
+ end if
+
+! ----- Solve system
+ if (spaceDime .eq. 2) then
+ dksi(1) = (residu(1)*matrix(2, 2)-residu(2)*matrix(1, 2))/det
+ dksi(2) = 0.d0
+ dbeta = (residu(2)*matrix(1, 1)-residu(1)*matrix(2, 1))/det
+ else if (spaceDime .eq. 3) then
+ dksi(1) = (residu(1)*(matrix(2, 2)*matrix(3, 3)-matrix(3, 2)*matrix(2, 3))+ &
+ residu(2)*(matrix(3, 2)*matrix(1, 3)-matrix(1, 2)*matrix(3, 3))+ &
+ residu(3)*(matrix(1, 2)*matrix(2, 3)-matrix(2, 2)*matrix(1, 3)))/det
+ dksi(2) = (residu(1)*(matrix(3, 1)*matrix(2, 3)-matrix(2, 1)*matrix(3, 3))+ &
+ residu(2)*(matrix(1, 1)*matrix(3, 3)-matrix(3, 1)*matrix(1, 3))+ &
+ residu(3)*(matrix(2, 1)*matrix(1, 3)-matrix(2, 3)*matrix(1, 1)))/det
+ dbeta = (residu(1)*(matrix(2, 1)*matrix(3, 2)-matrix(3, 1)*matrix(2, 2))+ &
+ residu(2)*(matrix(3, 1)*matrix(1, 2)-matrix(1, 1)*matrix(3, 2))+ &
+ residu(3)*(matrix(1, 1)*matrix(2, 2)-matrix(2, 1)*matrix(1, 2)))/det
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+! ----- Update
+ projPara%coorProjPara = projPara%coorProjPara+dksi
+ beta = beta+dbeta
+
+! ----- Save values if Newton avoids
+ if (dist .le. distMini) then
+ distMini = dist
+ ksiMini = projPara%coorProjPara
+ betaMini = beta
+ end if
+
+! ----- Convergence
+ refe = (projPara%coorProjPara(1)*projPara%coorProjPara(1)+ &
+ projPara%coorProjPara(2)*projPara%coorProjPara(2)+beta*beta)
+ if (refe .le. toleRela) then
+ toleNewt = toleAbso
+ test = sqrt(dksi(1)*dksi(1)+dksi(2)*dksi(2)+dbeta*dbeta)
+ else
+ toleNewt = toleRela
+ test = sqrt(dksi(1)*dksi(1)+dksi(2)*dksi(2)+dbeta*dbeta)/sqrt(refe)
+ end if
+
+! ----- Continue or not ?
+ if ((test .gt. toleNewt) .and. (iterNewt .lt. projPara%newtIterMaxi)) then
+ iterNewt = iterNewt+1
+ goto 20
+ else if ((iterNewt .ge. projPara%newtIterMaxi) .and. (test .gt. toleNewt)) then
+ projPara%coorProjPara = ksiMini
+ call elrfvf(cellTarget%cellCode, projPara%coorProjPara, shapeFunc)
+ call elrfdf(cellTarget%cellCode, projPara%coorProjPara, dShapeFunc)
+ call cellCompTang(cellTarget, spaceDime, dShapeFunc, projPara%tau1, projPara%tau2)
+ projPara%errorCode = 1
+ end if
+
+! ----- End of loop
+99 continue
+!
+ if (projPara%errorCode .eq. 1) then
+ WRITE (6, *) "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+ WRITE (6, *) "Newton algorithm for projection"
+ WRITE (6, *) " => failure "
+ WRITE (6, *) "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+ write (6, *) "Dimension de l'espace: ", spaceDime
+ write (6, *) "Coordonnées du point à projeter: ", &
+ projPara%coorPoinGlob(1), &
+ projPara%coorPoinGlob(2), &
+ projPara%coorPoinGlob(3)
+ write (6, *) "Direction de projection: ", &
+ projPara%projVect(1), &
+ projPara%projVect(2), &
+ projPara%projVect(3)
+ write (6, *) 'Maille cible de la projection: ', &
+ cellTarget%cellCode, &
+ cellTarget%nbNode
+ do iNode = 1, cellTarget%nbNode
+ write (6, *) ' Noeud ', iNode
+ write (6, *) ' (X,Y,Z)', &
+ cellTarget%coorNodeGlob(1, iNode), &
+ cellTarget%coorNodeGlob(2, iNode), &
+ cellTarget%coorNodeGlob(3, iNode)
+ end do
+ write (6, *) 'KSI : ', projPara%coorProjPara(1), projPara%coorProjPara(2)
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! inteCellChck
+!
+! Check intersection of cells (linearized)
+!
+! In meshPairing : main datastructure for pairing
+! In cellProj : geometric properties of projected cell
+! In nbNodeProj : number of projected nodes
+! In cellOrigLine : geometric properties of projected cell in origin reference frame
+! In cellTargLine : geometric properties of cell where cell has been projected
+! In normOrig : normal to origin cell
+! In normTarg : normal to target cell
+! Out inteIsEmpty : flag for empty intersection
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine inteCellChck(meshPairing, &
+ cellProj, nbNodeProj, &
+ cellOrigLine, cellTargLine, &
+ normOrig, normTarg, &
+ inteIsEmpty)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ type(CELL_GEOM), intent(in) :: cellProj
+ integer, intent(in) :: nbNodeProj
+ type(CELL_GEOM), intent(in) :: cellOrigLine, cellTargLine
+ real(kind=8), intent(in) :: normOrig(3), normTarg(3)
+ aster_logical, intent(out) :: inteIsEmpty
+! ----- Local
+ integer :: iNodeProj
+ integer :: listNodeNext(4)
+ real(kind=8) :: edgeOrig(3), edgeProj(3), vectProjOrig(3)
+ real(kind=8) :: sig, sp_ns_vsp, sp_np_vsp
+! ------------------------------------------------------------------------------------------------
+!
+ inteIsEmpty = ASTER_FALSE
+ ASSERT(cellProj%isLinear)
+ ASSERT(cellOrigLine%isLinear)
+ ASSERT(cellTargLine%isLinear)
+ ASSERT(cellProj%cellCode .eq. cellOrigLine%cellCode)
+
+ if (meshPairing%debug) then
+ WRITE (6, *) " Check intersection of cells"
+ WRITE (6, *) " ==========================="
+ end if
+
+! ----- Set index of next nodes
+ ASSERT(nbNodeProj .le. 4)
+ listNodeNext = 0
+ if (cellOrigLine%cellCode .eq. "SE2") then
+ listNodeNext(1:2) = nodeNextSEG
+ elseif (cellOrigLine%cellCode .eq. "TR3") then
+ listNodeNext(1:3) = nodeNextTRIA
+ elseif (cellOrigLine%cellCode .eq. "QU4") then
+ listNodeNext(1:4) = nodeNextQUAD
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+ do iNodeProj = 1, nbNodeProj
+! --------- Original edge
+ edgeOrig = 0.d0
+ edgeOrig = &
+ cellOrigLine%coorNodeGlob(:, listNodeNext(iNodeProj))- &
+ cellOrigLine%coorNodeGlob(:, iNodeProj)
+
+! --------- Projected edge
+ edgeProj = 0.d0
+ edgeProj = &
+ cellProj%coorNodeGlob(:, listNodeNext(iNodeProj))- &
+ cellProj%coorNodeGlob(:, iNodeProj)
+
+! --------- Compute vector start side to projected side
+ vectProjOrig = 0.d0
+ vectProjOrig = &
+ cellProj%coorNodeGlob(:, iNodeProj)- &
+ cellOrigLine%coorNodeGlob(:, iNodeProj)
+
+! --------- Sign of colinear product edgeProj . edgeOrig
+ sig = 0.d0
+ if (meshPairing%spaceDime .eq. 3) then
+ sig = edgeProj(1)*edgeOrig(1)+ &
+ edgeProj(2)*edgeOrig(2)+ &
+ edgeProj(3)*edgeOrig(3)
+ elseif (meshPairing%spaceDime .eq. 2) then
+ sig = edgeProj(1)*edgeOrig(1)+ &
+ edgeProj(2)*edgeOrig(2)
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+! --------- Sign of colinear product: direction of normal to edges
+ sp_ns_vsp = 0.d0
+ sp_np_vsp = 0.d0
+ if (meshPairing%spaceDime .eq. 3) then
+ sp_ns_vsp = normOrig(1)*vectProjOrig(1)+ &
+ normOrig(2)*vectProjOrig(2)+ &
+ normOrig(3)*vectProjOrig(3)
+ sp_np_vsp = normTarg(1)*vectProjOrig(1)+ &
+ normTarg(2)*vectProjOrig(2)+ &
+ normTarg(3)*vectProjOrig(3)
+ elseif (meshPairing%spaceDime .eq. 2) then
+ sp_ns_vsp = normOrig(1)*vectProjOrig(1)+ &
+ normOrig(2)*vectProjOrig(2)
+ sp_np_vsp = normTarg(1)*vectProjOrig(1)+ &
+ normTarg(2)*vectProjOrig(2)
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+! --------- Check signs
+ if (sig .lt. (0.d0-meshPairing%pairTole)) then
+! ------------- The two edges are opposite
+ inteIsEmpty = ASTER_TRUE
+ if (meshPairing%debug) then
+ WRITE (6, *) " Edge on original cell : ", edgeOrig
+ WRITE (6, *) " Edge on projected cell: ", edgeProj
+ WRITE (6, *) " Vector between edges : ", vectProjOrig
+ WRITE (6, *) " Normal to edge on origin cell : ", normOrig
+ WRITE (6, *) " Normal to edge on target cell : ", normTarg
+ WRITE (6, *) " Error: the two edges are opposite"
+ end if
+ exit
+ elseif (sp_ns_vsp .lt. (0.d0-meshPairing%pairTole) .and. &
+ sp_np_vsp .lt. (0.d0-meshPairing%pairTole)) then
+ inteIsEmpty = ASTER_TRUE
+ if (meshPairing%debug) then
+ WRITE (6, *) " Edge on original cell : ", edgeOrig
+ WRITE (6, *) " Edge on projected cell: ", edgeProj
+ WRITE (6, *) " Vector between edges : ", vectProjOrig
+ WRITE (6, *) " Normal to edge on original cell : ", normOrig
+ WRITE (6, *) " Normal to edge on target cell : ", normTarg
+ WRITE (6, *) " Error: les normales ne sont pas opposées"
+ end if
+ exit
+ elseif (sp_ns_vsp .gt. (0.d0+meshPairing%pairTole) .and. &
+ sp_np_vsp .gt. (0.d0+meshPairing%pairTole)) then
+ inteIsEmpty = ASTER_TRUE
+ if (meshPairing%debug) then
+ WRITE (6, *) " Edge on original cell : ", edgeOrig
+ WRITE (6, *) " Edge on projected cell: ", edgeProj
+ WRITE (6, *) " Vector between edges : ", vectProjOrig
+ WRITE (6, *) " Normal to edge on original cell : ", normOrig
+ WRITE (6, *) " Normal to edge on target cell : ", normTarg
+ WRITE (6, *) " Error: les normales ne sont pas opposées"
+ end if
+ exit
+ end if
+ end do
+ if (meshPairing%debug) then
+ if (inteIsEmpty) then
+ WRITE (6, *) " Empty intersection"
+ else
+ WRITE (6, *) " Not empty intersection"
+ end if
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellProjOnCell
+!
+! Project a cell to another one: cellOrig ===> cellProj
+!
+! In meshPairing : main datastructure for pairing
+! In cellOrig : geometric properties of cell to project
+! In cellOrigLine : geometric properties of cell to project (linearized)
+! In cellTargLine : geometric properties of cell where to project (linearized)
+! Out cellProj : geometric properties of projected cell
+! Out nbNodeProj : number of projected nodes
+! Out iret : return code error
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellProjOnCell(meshPairing, &
+ cellOrig, cellOrigLine, cellTargLine, &
+ cellProj, nbNodeProj, iret)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ type(CELL_GEOM), intent(in) :: cellOrig, cellOrigLine, cellTargLine
+ type(CELL_GEOM), intent(out) :: cellProj
+ integer, intent(out) :: nbNodeProj
+ integer, intent(out) :: iret
+! ----- Local
+ real(kind=8) :: normOrig(3), normTarg(3)
+ real(kind=8) :: ps, distCell
+ aster_logical :: inteIsEmpty
+! ------------------------------------------------------------------------------------------------
+!
+ ASSERT(cellTargLine%isSkin)
+ ASSERT(cellTargLine%isSkin)
+ ASSERT(cellTargLine%isLinear)
+ ASSERT(cellOrigLine%isLinear)
+
+ iret = ERR_PAIR_NONE
+ nbNodeProj = 0
+ if (meshPairing%debug) then
+ WRITE (6, *) " Compute projection of cell in another one"
+ WRITE (6, *) " ========================================="
+ end if
+
+! ----- Compute norms at barycenter
+ call cellCompNormAtBary(meshPairing%spaceDime, cellTargLine, normTarg)
+ call cellCompNormAtBary(meshPairing%spaceDime, cellOrigLine, normOrig)
+ if (meshPairing%debug) then
+ WRITE (6, *) " Barycenter normal (target): ", normTarg
+ WRITE (6, *) " Barycenter normal (origin): ", normOrig
+ end if
+
+! ----- If cells are orthogonal -> exit
+ ps = dot_product(normTarg(1:3), normOrig(1:3))
+ if (abs(ps) <= meshPairing%pairTole) then
+ if (meshPairing%debug) then
+ WRITE (6, *) " Cells are normal (", abs(ps), ") => STOP"
+ end if
+ iret = ERR_CELL_ORTH
+ goto 99
+ end if
+
+! ----- If distance between barycenter is too high -> exit
+ if (meshPairing%distRatio > 0) then
+ ASSERT(cellTargLine%diameter .ge. 0.d0)
+ ASSERT(cellOrig%diameter .ge. 0.d0)
+ distCell = norm2(cellTargLine%baryGlob-cellOrig%baryGlob)
+ if (distCell >= &
+ 2*meshPairing%distRatio*max(cellTargLine%diameter, cellOrig%diameter)) then
+ iret = ERR_CELL_OOR
+ if (meshPairing%debug) then
+ WRITE (6, *) " Cells are too far away (", distCell, ") => STOP"
+ end if
+ go to 99
+ end if
+ end if
+
+! ----- Project nodes in target cell parametric space using raytracing
+ call nodeProjOnCell(meshPairing, &
+ cellOrig, cellOrigLine, cellTargLine, &
+ cellProj, nbNodeProj, iret)
+ ASSERT(cellProj%isLinear)
+ if (iret .eq. ERR_PAIR_PROJ) then
+ goto 99
+ else
+ if (meshPairing%debug) then
+ WRITE (6, *) " Success of the projection of cell"
+ end if
+ end if
+
+! ----- Check if intersection is empty or not
+ call inteCellChck(meshPairing, &
+ cellProj, nbNodeProj, &
+ cellOrigLine, cellTargLine, &
+ normOrig, normTarg, &
+ inteIsEmpty)
+ if (inteIsEmpty) then
+ iret = ERR_INTE_VOID
+ end if
+
+99 continue
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! cellInteProj - prjint_ray
+!
+! Compute intersection and projection from cell to target cell
+!
+! In meshPairing : main datastructure for pairing
+! In cellOrig : general geometric properties of origin cell
+! In cellOrigLine : general geometric properties of linearized origin cell
+! In cellTargLine : general geometric properties of linearized target cell
+! Out iret : return code error
+! Out nbPoinInte : number of intersection points
+! Out poinInteOrig : coordinates of intersection points (in origin cell parametric space)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine cellInteProj(meshPairing, &
+ cellOrig, cellOrigLine, cellTargLine, &
+ iret_, &
+ nbPoinInte_, poinInteOrig_, &
+ inteArea_, inteNeigh_)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ type(CELL_GEOM), intent(in) :: cellOrig, cellOrigLine, cellTargLine
+ integer, optional, intent(out) :: iret_
+ integer, optional, intent(out) :: nbPoinInte_
+ real(kind=8), optional, intent(out) :: poinInteOrig_(2, MAX_NB_INTE)
+ real(kind=8), optional, intent(out) :: inteArea_
+ integer, optional, intent(out) :: inteNeigh_(MAX_NB_NEIGH)
+! ----- Local
+ aster_logical, parameter :: debug = ASTER_FALSE
+ integer :: iret, inteNeigh(MAX_NB_NEIGH)
+ integer :: nbPoinInteI
+ real(kind=8) :: poinInteTargI(2, 2*MAX_NB_INTE), poinInteOrigI(2, 2*MAX_NB_INTE)
+ integer :: nbPoinInteS
+ real(kind=8) :: poinInteTargS(2, MAX_NB_INTE), poinInteOrigS(2, MAX_NB_INTE)
+ integer :: nbPoinInte
+ real(kind=8) :: poinInteOrig(2, MAX_NB_INTE)
+ real(kind=8) :: inteArea
+ aster_logical :: errorProj, errorInte
+ type(CELL_GEOM) :: cellProj
+ integer :: nbCmpPara, nbNodeProj
+! ------------------------------------------------------------------------------------------------
+!
+ inteNeigh = 0
+ nbPoinInte = 0
+ poinInteOrig = 0.d0
+ inteArea = 0.d0
+ iret = ERR_PAIR_NONE
+ nbCmpPara = meshPairing%spaceDime-1
+
+! ----- Compute projection of cell on target cell
+ errorProj = ASTER_FALSE
+ call cellProjOnCell(meshPairing, &
+ cellOrig, cellOrigLine, cellTargLine, &
+ cellProj, nbNodeProj, iret)
+ if (iret .ne. ERR_PAIR_NONE) then
+ errorProj = ASTER_TRUE
+ goto 100
+ end if
+ if (meshPairing%debug) then
+ WRITE (6, *) " Intersection is OK"
+ end if
+
+! ----- Compute intersection in parametric space of target cell
+ nbPoinInteI = 0
+ poinInteTargI = 0.d0
+ poinInteOrigI = 0.d0
+ if (meshPairing%spaceDime .eq. 2) then
+ ASSERT(nbNodeProj .eq. 2)
+ call addPoinInte2D(meshPairing, cellProj, &
+ nbPoinInteI, poinInteTargI, poinInteOrigI, &
+ inteNeigh)
+ elseif (meshPairing%spaceDime .eq. 3) then
+ call addPoinInte3D(meshPairing, cellProj, nbNodeProj, &
+ cellOrigLine, cellTargLine, &
+ nbPoinInteI, poinInteTargI, poinInteOrigI, &
+ inteNeigh, iret)
+ call addPoinOnEdge(meshPairing, cellProj, nbNodeProj, &
+ cellOrigLine, cellTargLine, &
+ nbPoinInteI, poinInteTargI, poinInteOrigI, &
+ inteNeigh)
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ ASSERT(nbPoinInteI .le. 2*MAX_NB_INTE)
+
+! ----- Error management
+ errorInte = ASTER_FALSE
+ if (nbPoinInteI == 0 .or. iret == ERR_PAIR_MAST) then
+ errorInte = ASTER_TRUE
+ goto 100
+ end if
+
+! ----- Debug print
+ if (meshPairing%debug) then
+ WRITE (6, *) " Intersection (before re-ordering): ", nbPoinInteI, &
+ " points of intersection"
+ WRITE (6, *) " Target side : ", poinInteTargI(1:nbCmpPara, 1:nbPoinInteI)
+ WRITE (6, *) " Origin side : ", poinInteOrigI(1:nbCmpPara, 1:nbPoinInteI)
+ end if
+
+! ----- Sort list of intersection points
+ if ((nbPoinInteI .gt. 2 .and. meshPairing%spaceDime == 3) .or. &
+ (nbPoinInteI .ge. 2 .and. meshPairing%spaceDime == 2)) then
+ call intePoinSort(meshPairing, &
+ nbPoinInteI, poinInteTargI, poinInteOrigI, &
+ nbPoinInteS, poinInteTargS, poinInteOrigS)
+ else
+ ASSERT(nbPoinInteI .le. MAX_NB_INTE)
+ nbPoinInteS = nbPoinInteI
+ poinInteTargS(:, 1:nbPoinInteI) = poinInteTargI(:, 1:nbPoinInteI)
+ poinInteOrigS(:, 1:nbPoinInteI) = poinInteOrigI(:, 1:nbPoinInteI)
+ end if
+
+! ----- Error management
+ if (nbPoinInteS > MAX_NB_INTE) then
+ if (meshPairing%debug) then
+ WRITE (6, *) " Intersection (after re-ordering): ", nbPoinInteS, &
+ " points of intersection"
+ WRITE (6, *) " Too many points !"
+ end if
+ iret = ERR_PAIR_SLAV
+ go to 99
+ end if
+
+! ----- Debug print
+ if (meshPairing%debug) then
+ WRITE (6, *) " Intersection (after re-ordering): ", nbPoinInteS, &
+ " points of intersection"
+ WRITE (6, *) " Target side : ", poinInteTargS(1:nbCmpPara, 1:nbPoinInteS)
+ WRITE (6, *) " Origin side : ", poinInteOrigS(1:nbCmpPara, 1:nbPoinInteS)
+ end if
+
+! ----- All nodes have to be inside original cell
+ call intePoinInCell(meshPairing, cellOrigLine, &
+ nbPoinInteS, poinInteOrigS, poinInteOrig)
+ nbPoinInte = nbPoinInteS
+
+! ----- Compute weight of intersection
+ call inteCellArea(meshPairing%spaceDime, nbPoinInte, poinInteOrig, &
+ inteArea)
+ if (meshPairing%debug) then
+ WRITE (6, *) " Area of intersection : ", inteArea
+ end if
+
+! ----- Error
+100 continue
+ if (errorProj .or. errorInte) then
+ if (meshPairing%debug) then
+ WRITE (6, *) " Failure of intersection"
+ end if
+ nbPoinInte = 0
+ poinInteOrig = 0.d0
+ inteNeigh = 0
+ inteArea = 0.d0
+ else
+ if (meshPairing%debug) then
+ WRITE (6, *) " Success of intersection"
+ end if
+ end if
+
+! ----- Fatal error only in debug mode
+99 continue
+ if (debug) then
+ ASSERT(iret .ne. ERR_PAIR_NONE)
+ end if
+
+! ----- Outputs
+ if (present(inteNeigh_)) then
+ inteNeigh_ = inteNeigh
+ end if
+ if (present(nbPoinInte_)) then
+ nbPoinInte_ = nbPoinInte
+ end if
+ if (present(inteArea_)) then
+ inteArea_ = inteArea
+ end if
+ if (present(poinInteOrig_)) then
+ poinInteOrig_ = poinInteOrig
+ end if
+ if (present(iret_)) then
+ iret_ = iret
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! addPoinInte2D
+!
+! Compute intersection in parametric space of target cell - For 2D case (only segments)
+!
+! In meshPairing : main datastructure for pairing
+! In cellProj : geometric properties of original cell
+! Out nbPoinInte : number of intersection points
+! Out poinInteTarg : coordinates of intersection points in target cell
+! Out poinInteOrig : coordinates of intersection points in original cell
+! Out inteNeigh : active cell neighbours for each node of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine addPoinInte2D(meshPairing, cellProj, &
+ nbPoinInte, poinInteTarg, poinInteOrig, &
+ inteNeigh)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ type(CELL_GEOM), intent(in) :: cellProj
+ integer, intent(out) :: nbPoinInte
+ real(kind=8), intent(out) :: poinInteTarg(2, 2*MAX_NB_INTE), poinInteOrig(2, 2*MAX_NB_INTE)
+ integer, intent(out) :: inteNeigh(MAX_NB_NEIGH)
+! ----- Local
+ integer :: iNode, nbNode
+ real(kind=8) :: ksi
+ real(kind=8), parameter :: coorSegPara(2) = (/-1.d0, +1.d0/)
+ real(kind=8) :: ksiMini, ksiMaxi, t1
+! ------------------------------------------------------------------------------------------------
+!
+ nbPoinInte = 0
+ poinInteTarg = 0.d0
+ poinInteOrig = 0.d0
+ inteNeigh = 0
+ nbNode = cellProj%nbNode
+ ASSERT(nbNode .eq. 2)
+
+! ----- Add projected nodes inside target cell
+ do iNode = 1, nbNode
+ ksi = cellProj%coorNodePara(1, iNode)
+ if (ksi > (-1.d0-meshPairing%pairTole) .and. &
+ ksi < (1.d0+meshPairing%pairTole)) then
+ nbPoinInte = nbPoinInte+1
+ poinInteTarg(1, nbPoinInte) = ksi
+ poinInteOrig(1, nbPoinInte) = coorSegPara(iNode)
+ inteNeigh(iNode) = 1
+ end if
+ end do
+
+! ----- Add target nodes if they are inside projected cell
+ ksiMini = min(cellProj%coorNodePara(1, 1), cellProj%coorNodePara(1, 2))
+ ksiMaxi = max(cellProj%coorNodePara(1, 1), cellProj%coorNodePara(1, 2))
+ if ((ksiMini-meshPairing%pairTole) <= -1.d0 .and. &
+ -1.d0 <= (ksiMaxi+meshPairing%pairTole)) then
+ nbPoinInte = nbPoinInte+1
+ poinInteTarg(1, nbPoinInte) = coorSegPara(1)
+ if (abs(-1.d0-cellProj%coorNodePara(1, 1)) < meshPairing%pairTole) then
+ poinInteOrig(1, nbPoinInte) = coorSegPara(1)
+ else
+ t1 = (-1.d0-cellProj%coorNodePara(1, 1))/ &
+ (cellProj%coorNodePara(1, 2)-cellProj%coorNodePara(1, 1))
+ poinInteOrig(1, nbPoinInte) = 2*t1-1
+ end if
+ end if
+ if ((ksiMini-meshPairing%pairTole) <= 1.d0 .and. &
+ 1.d0 <= (ksiMaxi+meshPairing%pairTole)) then
+ nbPoinInte = nbPoinInte+1
+ poinInteTarg(1, nbPoinInte) = coorSegPara(2)
+ if (abs(1.d0-cellProj%coorNodePara(1, 1)) .lt. meshPairing%pairTole) then
+ poinInteOrig(1, nbPoinInte) = coorSegPara(1)
+ else
+ t1 = (1.d0-cellProj%coorNodePara(1, 1))/ &
+ (cellProj%coorNodePara(1, 2)-cellProj%coorNodePara(1, 1))
+ poinInteOrig(1, nbPoinInte) = 2*t1-1
+ end if
+ end if
+ if (meshPairing%debug) then
+ WRITE (6, *) " Neighbours : ", inteNeigh
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! addPoinInte3D
+!
+! Compute intersection in parametric master space - For 3D case
+!
+! In meshPairing : main datastructure for pairing
+! In cellProj : geometric properties of projected cell from slave cell
+! In nbNodeProj : number of projected nodes
+! In cellOrigLine : geometric properties of cell to project (linearized)
+! In cellTargLine : geometric properties of cell where to project (linearized)
+! Out nbPoinInte : number of intersection points
+! Out poinInteTarg : coordinates of intersection points in target cell
+! Out poinInteOrig : coordinates of intersection points in original cell
+! Out inteNeigh : active cell neighbours for each node of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine addPoinInte3D(meshPairing, cellProj, nbNodeProj, &
+ cellOrigLine, cellTargLine, &
+ nbPoinInte, poinInteTarg, poinInteOrig, &
+ inteNeigh, iret)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ type(CELL_GEOM), intent(in) :: cellProj
+ integer, intent(in) :: nbNodeProj
+ type(CELL_GEOM), intent(in) :: cellOrigLine, cellTargLine
+ integer, intent(out) :: nbPoinInte
+ real(kind=8), intent(out) :: poinInteTarg(2, 2*MAX_NB_INTE), poinInteOrig(2, 2*MAX_NB_INTE)
+ integer, intent(out) :: inteNeigh(MAX_NB_NEIGH)
+ integer, intent(out) :: iret
+! ----- Local
+ aster_logical :: pointIsInside
+ real(kind=8) :: nodeProjPara(2), origCoorPara(2)
+ integer :: listNodePrev(4)
+ integer :: iNodeTarg, iNodeProj, errorInside
+! ------------------------------------------------------------------------------------------------
+!
+ inteNeigh = 0
+ nbPoinInte = 0
+ iret = ERR_PAIR_NONE
+
+! ----- Liste orientée des noeuds projetés de la cellule
+ ASSERT(nbNodeProj .le. 4)
+ listNodePrev = 0
+ if (cellOrigLine%cellCode .eq. "TR3") then
+ listNodePrev(1:3) = nodePrevTRIA
+ elseif (cellOrigLine%cellCode .eq. "QU4") then
+ listNodePrev(1:4) = nodePrevQUAD
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+! ----- Add projection of original nodes inside target cell (parametric space)
+ do iNodeProj = 1, nbNodeProj
+ nodeProjPara(1:2) = cellProj%coorNodePara(1:2, iNodeProj)
+ if (meshPairing%debug) then
+ WRITE (6, *) "Project original nodes inside target cell: ", &
+ iNodeProj, nodeProjPara(1:2)
+ WRITE (6, *) " on cell ", cellTargLine%cellCode
+ end if
+ pointIsInside = cellPoinInside(cellTargLine, meshPairing%pairTole, nodeProjPara)
+ if (meshPairing%debug) then
+ if (pointIsInside) then
+ WRITE (6, *) " => is inside"
+ else
+ WRITE (6, *) " => is NOT inside"
+ end if
+ end if
+ if (pointIsInside) then
+ nbPoinInte = nbPoinInte+1
+ ASSERT(nbPoinInte .le. MAX_NB_INTE)
+ poinInteTarg(:, nbPoinInte) = nodeProjPara
+ poinInteOrig(:, nbPoinInte) = cellOrigLine%coorNodePara(1:2, iNodeProj)
+ if (meshPairing%debug) then
+ WRITE (6, *) " nbPoinInte :", nbPoinInte
+ WRITE (6, *) " Coor. targ.:", nodeProjPara
+ WRITE (6, *) " Coor. orig.:", cellOrigLine%coorNodePara(1:2, iNodeProj)
+ end if
+ inteNeigh(iNodeProj) = 1
+ inteNeigh(listNodePrev(iNodeProj)) = 1
+ end if
+ end do
+
+! ----- Add targeted nodes if they are inside projected original cell
+ do iNodeTarg = 1, cellTargLine%nbNode
+! --------- Current parametric coordinates of targeted node
+ nodeProjPara = cellTargLine%coorNodePara(1:2, iNodeTarg)
+ if (meshPairing%debug) then
+ WRITE (6, *) "Project targeted nodes inside original cell: ", &
+ iNodeTarg, nodeProjPara(1:2)
+ WRITE (6, *) " on cell ", cellProj%cellCode
+ end if
+
+! --------- Test
+ call poinIsInsideOtherCell(meshPairing%pairTole, meshPairing%debug, &
+ nodeProjPara, cellProj, &
+ origCoorPara, pointIsInside, &
+ errorInside)
+ if (meshPairing%debug) then
+ if (pointIsInside) then
+ WRITE (6, *) " => is inside"
+ else
+ WRITE (6, *) " => is NOT inside"
+ end if
+ end if
+
+ if (pointIsInside) then
+ nbPoinInte = nbPoinInte+1
+ poinInteTarg(:, nbPoinInte) = nodeProjPara
+ poinInteOrig(:, nbPoinInte) = origCoorPara
+ if (meshPairing%debug) then
+ WRITE (6, *) " nbPoinInte :", nbPoinInte
+ WRITE (6, *) " Coor. targ.:", nodeProjPara
+ WRITE (6, *) " Coor. orig.:", origCoorPara
+ end if
+ end if
+ if (errorInside == ERR_CELL_DEGE) then
+ iret = ERR_PAIR_MAST
+ if (meshPairing%debug) then
+ WRITE (6, *) "Error during projection"
+ end if
+ end if
+ end do
+ if (meshPairing%debug) then
+ WRITE (6, *) " Neighbours after points intersection : ", inteNeigh
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! poinIsInsideOtherCell
+!
+! Detect if point is inside other cell
+!
+! In projTole : tolerance for projection
+! In poinCoorPara : coordinates of point in parametric space
+! In cellGeom : geometric properties of cell
+! Out origCoorPara
+! Out poinIsInside
+! Out error
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine poinIsInsideOtherCell(projTole, debug, &
+ poinCoorPara, cellGeom, &
+ origCoorPara, poinIsInside, &
+ error)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ real(kind=8), intent(in) :: projTole
+ aster_logical, intent(in) :: debug
+ type(CELL_GEOM), intent(in) :: cellGeom
+ real(kind=8), intent(in) :: poinCoorPara(2)
+ real(kind=8), intent(out) :: origCoorPara(2)
+ aster_logical, intent(out) :: poinIsInside
+ integer, intent(out) :: error
+! ----- Local
+ character(len=8) :: cellCode
+ real(kind=8) :: cellCoorPara(2, MT_NNOMAX3D)
+ real(kind=8) :: v0(2), v1(2), v2(2), d00, d10, d11, m, u, v
+ real(kind=8) :: d02, d12
+! ------------------------------------------------------------------------------------------------
+!
+ poinIsInside = ASTER_FALSE
+ error = ERR_PAIR_NONE
+ cellCode = cellGeom%cellCode
+ cellCoorPara = cellGeom%coorNodePara(1:2, :)
+ ASSERT(celLGeom%isSkin)
+ ASSERT(cellGeom%isLinear)
+ ASSERT(cellGeom%nbNode .le. MT_NNOMAX2D)
+ origCoorPara = 0.d0
+
+! ----- First detect with triangle
+
+! ----- Vectorial basis for element
+ v0 = cellCoorPara(:, 2)-cellCoorPara(:, 1)
+ v1 = cellCoorPara(:, 3)-cellCoorPara(:, 1)
+ d00 = v0(1)*v0(1)+v0(2)*v0(2)
+ d10 = v0(1)*v1(1)+v0(2)*v1(2)
+ d11 = v1(1)*v1(1)+v1(2)*v1(2)
+ m = (d00*d11-d10*d10)
+ if (debug) then
+ WRITE (6, *) "Base vectorielle: ", v0, v1, m
+ end if
+
+! ----- Degenerated vectorial basis for element (colinear vectors) => exit
+ if (abs(m) .le. projTole) then
+ poinIsInside = ASTER_FALSE
+ error = ERR_CELL_DEGE
+ goto 99
+ end if
+
+! ----- Coordinates of point in element's basis
+ v2 = poinCoorPara(:)-cellCoorPara(:, 1)
+ d02 = v0(1)*v2(1)+v0(2)*v2(2)
+ d12 = v1(1)*v2(1)+v1(2)*v2(2)
+ if (debug) then
+ WRITE (6, *) "Base vectorielle 2: ", v2
+ end if
+
+! ----- Point is in element => exit
+ if (sqrt(v2(1)**2+v2(2)**2) .le. 0.d0+projTole) then
+ poinIsInside = ASTER_TRUE
+ if (cellCode .eq. 'TR3') then
+ origCoorPara(1) = 0.d0
+ origCoorPara(2) = 0.d0
+ elseif (cellCode .eq. 'QU4') then
+ origCoorPara(1) = -1.d0
+ origCoorPara(2) = -1.d0
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ if (debug) then
+ WRITE (6, *) "Dedans sans extension"
+ end if
+ goto 99
+ end if
+
+! ----- Extension with projTole
+ u = 1/m*(d11*d02-d10*d12)
+ v = 1/m*(d00*d12-d10*d02)
+ if (debug) then
+ WRITE (6, *) "Extension T3: ", u, v, projTole
+ end if
+ if (u .ge. (0.d0-projTole) .and. &
+ v .ge. (0.d0-projTole) .and. &
+ (u+v) .le. (1.d0+projTole)) then
+ poinIsInside = ASTER_TRUE
+ if (cellCode .eq. 'TR3') then
+ origCoorPara(1) = 0.d0+u
+ origCoorPara(2) = 0.d0+v
+ elseif (cellCode .eq. 'QU4') then
+ origCoorPara(1) = -1.d0+u*2+v*2
+ origCoorPara(2) = -1.d0+v*2
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ if (debug) then
+ WRITE (6, *) "Dedans avec extension"
+ end if
+ goto 99
+ else
+ poinIsInside = ASTER_FALSE
+ end if
+
+ if (cellCode .eq. 'QU4') then
+! --------- Vectorial basis for element
+ v0(:) = cellCoorPara(:, 3)-cellCoorPara(:, 1)
+ v1(:) = cellCoorPara(:, 4)-cellCoorPara(:, 1)
+ d00 = v0(1)*v0(1)+v0(2)*v0(2)
+ d10 = v0(1)*v1(1)+v0(2)*v1(2)
+ d11 = v1(1)*v1(1)+v1(2)*v1(2)
+ m = (d00*d11-d10*d10)
+ if (debug) then
+ WRITE (6, *) "Base vectorielle Q4-1: ", v0, v1, m
+ end if
+
+! --------- Degenerated vectorial basis for element (colinear vectors) => exit
+ if (abs(m) .le. projTole) then
+ poinIsInside = ASTER_FALSE
+ error = ERR_CELL_DEGE
+ goto 99
+ end if
+
+! --------- Coordinates of point in element's basis
+ v2(:) = poinCoorPara(:)-cellCoorPara(:, 1)
+ d02 = v0(1)*v2(1)+v0(2)*v2(2)
+ d12 = v1(1)*v2(1)+v1(2)*v2(2)
+ if (debug) then
+ WRITE (6, *) "Base vectorielle Q4-2: ", v2
+ end if
+
+! --------- Point is in element => exit
+ if (sqrt(v2(1)**2+v2(2)**2) .le. 0.d0+projTole) then
+ poinIsInside = ASTER_TRUE
+ if (cellCode .eq. 'QU4') then
+ origCoorPara(1) = -1.d0
+ origCoorPara(2) = -1.d0
+ end if
+ if (debug) then
+ WRITE (6, *) "Dedans sans extension"
+ end if
+ goto 99
+ end if
+
+! --------- Extension with projTole
+ u = 1/m*(d11*d02-d10*d12)
+ v = 1/m*(d00*d12-d10*d02)
+ if (debug) then
+ WRITE (6, *) "Extension Q4: ", u, v, projTole
+ end if
+ if (u .ge. (0.d0-projTole) .and. &
+ v .ge. (0.d0-projTole) .and. &
+ (u+v) .le. (1.d0+projTole)) then
+ poinIsInside = ASTER_TRUE
+ if (cellCode .eq. 'QU4') then
+ origCoorPara(1) = -1.d0+u*2
+ origCoorPara(2) = -1.d0+v*2+u*2
+ end if
+ if (debug) then
+ WRITE (6, *) "Dedans avec extension"
+ end if
+ goto 99
+ else
+ poinIsInside = ASTER_FALSE
+ end if
+ end if
+!
+99 continue
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! inteCellSegm
+!
+! Compute intersection between segment and (linearized) cell
+!
+! In meshPairing : main datastructure for pairing
+! In coorSegm : coordinates of segment
+! In cellLine : general geometric properties of linearized cell
+! IO nbPoinInte : number of intersection points
+! IO poinInte : coordinates of intersection points
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine inteCellSegm(meshPairing, &
+ coorSegm, cellLine, &
+ nbPoinInte, poinInte)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ real(kind=8), intent(in) :: coorSegm(2, 2)
+ type(CELL_GEOM), intent(in) :: cellLine
+ integer, intent(inout) :: nbPoinInte
+ real(kind=8), intent(inout) :: poinInte(2, 2*MAX_NB_INTE)
+! ----- Local
+ integer :: nbNode, iNode
+ real(kind=8) :: a, b, c, d
+ real(kind=8) :: t1, t2, det, aux(2), norm
+ real(kind=8) :: x1, y1, x2, y2
+ integer :: listNodeNext(4)
+! ------------------------------------------------------------------------------------------------
+!
+ ASSERT(cellLine%isLinear)
+ nbNode = cellLine%nbNode
+
+! ----- Set index of next nodes
+ ASSERT(nbNode .le. 4)
+ listNodeNext = 0
+ if (cellLine%cellCode .eq. "SE2") then
+ listNodeNext(1:2) = nodeNextSEG
+ elseif (cellLine%cellCode .eq. "TR3") then
+ listNodeNext(1:3) = nodeNextTRIA
+ elseif (cellLine%cellCode .eq. "QU4") then
+ listNodeNext(1:4) = nodeNextQUAD
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+! ----- Coefficients for parametric equation of segment
+ x1 = coorSegm(1, 1)
+ y1 = coorSegm(2, 1)
+ a = coorSegm(1, 2)-x1
+ b = coorSegm(2, 2)-y1
+
+ if (meshPairing%debug) then
+ WRITE (6, *) " Intersection"
+ WRITE (6, *) " Segment 1: ", x1, y1
+ WRITE (6, *) " Parametric equation: ", a, b
+ end if
+
+! ----- Loop on edges of element
+ do iNode = 1, nbNode
+! --------- Current segment in cell
+ x2 = cellLine%coorNodePara(1, iNode)
+ y2 = cellLine%coorNodePara(2, iNode)
+
+! --------- Coefficients for parametric equation of segment in cell
+ c = cellLine%coorNodePara(1, listNodeNext(iNode))-x2
+ d = cellLine%coorNodePara(2, listNodeNext(iNode))-y2
+
+! --------- Compute intersection
+ det = b*c-a*d
+ if (meshPairing%debug) then
+ WRITE (6, *) " Segment : ", iNode, x2, y2
+ WRITE (6, *) " Parametric equation: ", c, d
+ end if
+
+ if (sqrt(det**2) .gt. meshPairing%pairTole) then
+ t1 = 1/det*(d*(x1-x2)-c*(y1-y2))
+ t2 = 1/det*(b*(x1-x2)-a*(y1-y2))
+ aux(1) = (-t1*a-t2*c)-(x1-x2)
+ aux(2) = (t1*b+t2*d)-(y1-y2)
+ norm = sqrt(aux(1)**2+aux(2)**2)
+ else
+ t1 = -1.d0
+ t2 = -1.d0
+ end if
+
+! --------- Test intersection
+ if (t1 .lt. 1.d0+meshPairing%pairTole .and. &
+ t1 .gt. 0.d0-meshPairing%pairTole .and. &
+ t2 .lt. 1.d0+meshPairing%pairTole .and. &
+ t2 .gt. 0.d0-meshPairing%pairTole) then
+ nbPoinInte = nbPoinInte+1
+ ASSERT(nbPoinInte .le. 2*MAX_NB_INTE)
+ poinInte(1, nbPoinInte) = (t2*c+x2+t1*a+x1)/2.d0
+ poinInte(2, nbPoinInte) = (t2*d+y2+t1*b+y1)/2.d0
+ if (meshPairing%debug) then
+ WRITE (6, *) " -> intersection détectée: ", &
+ nbPoinInte, poinInte(:, nbPoinInte)
+ end if
+ end if
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! addPoinOnEdge
+!
+! Compute intersection of edges for 3D case
+!
+! In meshPairing : main datastructure for pairing
+! In cellProj : geometric properties of projected cell from slave cell
+! In nbNodeProj : number of projected nodes
+! In cellOrigLine : general geometric properties of linearized origin cell
+! In cellTargLine : general geometric properties of linearized target cell
+! Out nbPoinInte : number of intersection points
+! Out poinInteTarg : coordinates of intersection points on target cell
+! Out poinInteOrig : coordinates of intersection points on origin cell
+! IO inteNeigh : active cell neighbours for each node of cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine addPoinOnEdge(meshPairing, cellProj, nbNodeProj, &
+ cellOrigLine, cellTargLine, &
+ nbPoinInte, poinInteTarg, poinInteOrig, &
+ inteNeigh)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ type(CELL_GEOM), intent(in) :: cellProj
+ integer, intent(in) :: nbNodeProj
+ type(CELL_GEOM), intent(in) :: cellOrigLine, cellTargLine
+ integer, intent(inout) :: nbPoinInte
+ real(kind=8), intent(inout) :: poinInteTarg(2, 2*MAX_NB_INTE)
+ real(kind=8), intent(inout) :: poinInteOrig(2, 2*MAX_NB_INTE)
+ integer, intent(inout) :: inteNeigh(MAX_NB_NEIGH)
+! ----- Local
+ real(kind=8) :: coorSegmProj(2, 2), t1, t2
+ real(kind=8) :: coorSegmOrig(2, 2)
+ integer :: nbPoinAdd, nbPoinInteAv
+ integer :: iPoinAdd, listNodeNext(4), iNodeProj
+! ------------------------------------------------------------------------------------------------
+!
+ ASSERT(nbNodeProj .le. 4)
+
+! ----- Set index of next nodes
+ listNodeNext = 0
+ if (cellOrigLine%cellCode .eq. "SE2") then
+ listNodeNext(1:2) = nodeNextSEG
+ elseif (cellOrigLine%cellCode .eq. "TR3") then
+ listNodeNext(1:3) = nodeNextTRIA
+ elseif (cellOrigLine%cellCode .eq. "QU4") then
+ listNodeNext(1:4) = nodeNextQUAD
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+! ----- Intersection of edges
+ do iNodeProj = 1, nbNodeProj
+
+! --------- Coordinates of segment from projected cell (in target cell reference frame)
+ coorSegmProj(1:2, 1) = cellProj%coorNodePara(1:2, iNodeProj)
+ coorSegmProj(1:2, 2) = cellProj%coorNodePara(1:2, listNodeNext(iNodeProj))
+
+! --------- Coordinates of segment from original cell (in original cell reference frame)
+ coorSegmOrig(1:2, 1) = cellOrigLine%coorNodePara(1:2, iNodeProj)
+ coorSegmOrig(1:2, 2) = cellOrigLine%coorNodePara(1:2, listNodeNext(iNodeProj))
+
+ if (meshPairing%debug) then
+ WRITE (6, *) "Intersection of edges: ", &
+ iNodeProj, coorSegmProj
+ WRITE (6, *) " Intersection points before: ", &
+ nbPoinInte, poinInteTarg
+ end if
+
+! --------- Compute intersection between edge of master and projected slave cells
+ nbPoinInteAv = nbPoinInte
+ call inteCellSegm(meshPairing, &
+ coorSegmProj, cellTargLine, &
+ nbPoinInte, poinInteTarg)
+ if (meshPairing%debug) then
+ WRITE (6, *) " => intersection points: ", &
+ nbPoinInte, poinInteTarg
+ end if
+
+! --------- Number of intersection points to add
+ nbPoinAdd = nbPoinInte-nbPoinInteAv
+ if (nbPoinAdd .gt. 0) then
+ inteNeigh(iNodeProj) = 1
+ do iPoinAdd = 1, nbPoinAdd
+ t1 = 0.d0
+ t2 = 0.d0
+ if (abs(poinInteTarg(1, nbPoinInteAv+iPoinAdd)-coorSegmProj(1, 1)) .gt. &
+ meshPairing%pairTole) then
+ t1 = (coorSegmProj(1, 2)-coorSegmProj(1, 1))/ &
+ (poinInteTarg(1, nbPoinInteAv+iPoinAdd)-coorSegmProj(1, 1))
+ poinInteOrig(1, nbPoinInteAv+iPoinAdd) = &
+ (1.0/t1)*(coorSegmOrig(1, 2)-coorSegmOrig(1, 1))+coorSegmOrig(1, 1)
+ else
+ poinInteOrig(1, nbPoinInteAv+iPoinAdd) = &
+ coorSegmOrig(1, 1)
+ end if
+ if (abs(poinInteTarg(2, nbPoinInteAv+iPoinAdd)-coorSegmProj(2, 1)) .gt. &
+ meshPairing%pairTole) then
+ t2 = (coorSegmProj(2, 2)-coorSegmProj(2, 1))/ &
+ (poinInteTarg(2, nbPoinInteAv+iPoinAdd)-coorSegmProj(2, 1))
+ poinInteOrig(2, nbPoinInteAv+iPoinAdd) = &
+ (1.0/t2)*(coorSegmOrig(2, 2)-coorSegmOrig(2, 1))+coorSegmOrig(2, 1)
+ poinInteOrig(1, nbPoinInteAv+iPoinAdd) = &
+ (1.0/t2)*(coorSegmOrig(1, 2)-coorSegmOrig(1, 1))+coorSegmOrig(1, 1)
+ else
+ if (t1 .lt. meshPairing%pairTole) then
+ poinInteOrig(2, nbPoinInteAv+iPoinAdd) = &
+ coorSegmOrig(2, 1)
+ else
+ poinInteOrig(2, nbPoinInteAv+iPoinAdd) = &
+ (1.0/t1)*(coorSegmOrig(2, 2)-coorSegmOrig(2, 1))+coorSegmOrig(2, 1)
+ end if
+ end if
+ end do
+ end if
+ end do
+ if (meshPairing%debug) then
+ WRITE (6, *) " Neighbours after segments intersection : ", inteNeigh
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! pairGetStartCells - ap_infast_n
+!
+! Get cell for starting search
+!
+! In meshPairing : main datastructure for pairing
+! Ptr nodeCoor : updated coordinates of nodes of mesh
+! Ptr meshTypeGeom : pointer to type of cells in mesh
+! Ptr meshConx : pointers to connectivity of mesh
+! meshConxCumu
+! Ptr mastConxInv : pointers to inverse conenctivity of master cells
+! mastConxInvCumu
+! In nbCellSlav : number of slave cells
+! In listCellSlav : list of slave cells
+! In cellSlavFlag : flag for slave cell has been used in a pair
+! 0 - Never used
+! 1 - Used as starting point
+! 2 - Used
+! In nbCellMast : number of master cells
+! In listCellMast : list of master cells
+! In nbNodeMast : number of master nodes
+! In listNodeMast : list of master nodes
+! In nbMastStart : number of master cells used as a start cell
+! In cellMastStart : list of master cells used as a start cell
+! In nbSlavStart : number of slave cells used as a start cell
+! In cellSlavStart : list of slave cells used as a start cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine pairGetStartCells(meshPairing, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ mastConxInv, mastConxInvCumu, &
+ nbCellSlav, listCellSlav, cellSlavFlag, &
+ nbCellMast, listCellMast, &
+ nbNodeMast, listNodeMast, &
+ nbMastStart, cellMastStart, &
+ nbSlavStart, cellSlavStart)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ real(kind=8), pointer :: nodeCoor(:)
+ integer, pointer :: meshTypeGeom(:)
+ integer, pointer :: meshConx(:), meshConxCumu(:)
+ integer, pointer :: mastConxInv(:), mastConxInvCumu(:)
+ integer, intent(in) :: nbCellSlav, listCellSlav(nbCellSlav)
+ integer, pointer :: cellSlavFlag(:)
+ integer, intent(in) :: nbCellMast, listCellMast(nbCellMast)
+ integer, intent(in) :: nbNodeMast, listNodeMast(nbNodeMast)
+ integer, intent(out) :: nbMastStart, cellMastStart(nbCellMast)
+ integer, intent(out) :: nbSlavStart, cellSlavStart(nbCellSlav)
+! ----- Local
+ integer :: iCellSlav, iCellMast
+ integer :: cellSlavNume, cellSlavIndx
+ integer :: cellMastNume
+ type(CELL_GEOM) :: cellSlav, cellSlavLine
+ type(CELL_GEOM) :: cellMast, cellMastLine
+ integer :: nodeNumeClosest
+ integer :: slavIndxMini
+ integer :: nbCellToNode, cellToNode(nbCellMast)
+ real(kind=8) :: inteArea
+! ------------------------------------------------------------------------------------------------
+!
+ slavIndxMini = minval(listCellSlav)
+ nbMastStart = 0
+ cellMastStart = 0
+ nbSlavStart = 0
+ cellSlavStart = 0
+
+! ----- Loop on slave elements
+ do iCellSlav = 1, nbCellSlav
+! --------- Get current slave element
+ cellSlavNume = listCellSlav(iCellSlav)
+ cellSlavIndx = cellSlavNume+1-slavIndxMini
+ if (meshPairing%debug) then
+ WRITE (6, *) " Current slave cell : ", cellSlavNume
+ end if
+
+! --------- Already tracked ?
+ if (cellSlavFlag(cellSlavIndx) .eq. 0) then
+ if (meshPairing%debug) then
+ WRITE (6, *) " Current slave cell not yet tracked"
+ end if
+
+! ------------- Create slave cell
+ call cellCreate(cellSlavNume, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ cellSlav, cellSlavLine)
+ if (meshPairing%debug) then
+ WRITE (6, *) "Properties of slave cell"
+ WRITE (6, *) "========================"
+ call cellDebug(cellSlav)
+ end if
+
+! ------------- Find the closest master node from center of slave cell
+ if (meshPairing%debug) then
+ WRITE (6, *) " Seek for closest master node from center of slave cell"
+ end if
+ call getClosestNodesFromCell(cellSlav, nodeCoor, &
+ nbNodeMast, listNodeMast, &
+ nodeNumeClosest)
+ if (meshPairing%debug) then
+ WRITE (6, *) " => ", nodeNumeClosest
+ end if
+
+! ------------- Construct list of master cells attached to this node
+ if (meshPairing%debug) then
+ WRITE (6, *) " Get list of cells attached to this node"
+ end if
+ call getCellsFromNode(nodeNumeClosest, &
+ mastConxInv, mastConxInvCumu, &
+ nbCellMast, listCellMast, &
+ nbCellToNode, cellToNode)
+ if (meshPairing%debug) then
+ WRITE (6, *) " => Number of cells: ", nbCellToNode
+ WRITE (6, *) " => Cells connected: ", cellToNode(1:nbCellToNode)
+ end if
+
+! ------------- Loop on master elements linked to the closest master node
+ do iCellMast = 1, nbCellToNode
+ if (meshPairing%debug) then
+ WRITE (6, *) " Seek for closest master cell"
+ end if
+! ----------------- Get current master cell
+ cellMastNume = cellToNode(iCellMast)
+ if (meshPairing%debug) then
+ WRITE (6, *) " Current master cell : ", cellMastNume
+ end if
+
+! ----------------- Create master cell
+ call cellCreate(cellMastNume, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ cellMast, cellMastLine)
+ if (meshPairing%debug) then
+ WRITE (6, *) "Properties of master cell"
+ WRITE (6, *) "========================"
+ call cellDebug(cellMast)
+ end if
+
+! ----------------- Projection/intersection of the two cells
+ if (meshPairing%debug) then
+ WRITE (6, *) " Compute intersection and projection in slave space"
+ end if
+ call cellInteProj(meshPairing, &
+ cellMast, cellMastLine, cellSlavLine, &
+ inteArea_=inteArea)
+ if (meshPairing%debug) then
+ WRITE (6, *) " Intersection area: ", inteArea
+ end if
+
+! ----------------- Set start elements
+ if (inteArea .gt. 100*meshPairing%pairTole) then
+ cellMastStart(1) = cellMastNume
+ nbMastStart = 1
+ cellSlavStart(1) = cellSlavNume
+ nbSlavStart = 1
+ cellSlavFlag(cellSlavIndx) = 1
+ goto 100
+ end if
+ end do
+ else
+ if (meshPairing%debug) then
+ WRITE (6, *) " Current slave cell is already tracked"
+ end if
+ end if
+ cellSlavFlag(cellSlavIndx) = 2
+ end do
+100 continue
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! intePoinSort
+!
+! Sort points of intersection
+!
+! In meshPairing : main datastructure for pairing
+! In nbPoinInteIn : number of intersection points (input)
+! In poinInteTargIn : intersection points on target cell (input)
+! In poinInteOrigIn : intersection points on original cell (input)
+! Out nbPoinInteOut : number of intersection points (output)
+! Out poinInteTargOut : intersection points on target cell (output)
+! Out poinInteOrigOut : intersection points on original cell (output)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine intePoinSort(meshPairing, &
+ nbPoinInteIn, poinInteTargIn, poinInteOrigIn, &
+ nbPoinInteOut, poinInteTargOut, poinInteOrigOut)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ integer, intent(in) :: nbPoinInteIn
+ real(kind=8), intent(in) :: poinInteTargIn(2, 2*MAX_NB_INTE)
+ real(kind=8), intent(in) :: poinInteOrigIn(2, 2*MAX_NB_INTE)
+ integer, intent(out) :: nbPoinInteOut
+ real(kind=8), intent(out) :: poinInteTargOut(2, MAX_NB_INTE)
+ real(kind=8), intent(out) :: poinInteOrigOut(2, MAX_NB_INTE)
+! ----- Local
+ real(kind=8) :: poinInteSort1(2, 2*MAX_NB_INTE), poinInteSort2(2, 2*MAX_NB_INTE)
+ real(kind=8) :: angle(2*MAX_NB_INTE)
+ real(kind=8) :: v(2), norm, bary(2)
+ integer :: iPoinInte, angle_sorted(2*MAX_NB_INTE), listPoinNext(2*MAX_NB_INTE)
+! ------------------------------------------------------------------------------------------------
+!
+ bary = 0.d0
+ v = 0.d0
+ nbPoinInteOut = 0
+ poinInteSort1 = 0.d0
+ poinInteSort2 = 0.d0
+ poinInteTargOut = 0.d0
+ poinInteOrigOut = 0.d0
+
+! ----- Set index of next points
+ do iPoinInte = 2, nbPoinInteIn
+ listPoinNext(iPoinInte-1) = iPoinInte
+ end do
+ listPoinNext(nbPoinInteIn) = 1
+
+ if (meshPairing%spaceDime .eq. 3) then
+! --------- Coordinates of barycenter
+ do iPoinInte = 1, nbPoinInteIn
+ bary(:) = bary(:)+poinInteTargIn(:, iPoinInte)/real(nbPoinInteIn)
+ end do
+
+! --------- Compute angles
+ do iPoinInte = 1, nbPoinInteIn
+ v(:) = poinInteTargIn(:, iPoinInte)-bary(:)
+ angle(iPoinInte) = atan2(v(1), v(2))
+ end do
+
+! --------- Sort angles
+ call ordr8(angle, nbPoinInteIn, angle_sorted)
+
+! --------- Sort
+ nbPoinInteOut = 0
+ do iPoinInte = 1, nbPoinInteIn
+ norm = sqrt((angle(angle_sorted(iPoinInte))- &
+ angle(angle_sorted(listPoinNext(iPoinInte))))**2)
+ if (norm .gt. 10*meshPairing%pairTole) then
+ nbPoinInteOut = nbPoinInteOut+1
+ poinInteSort1(1:2, nbPoinInteOut) = poinInteTargIn(1:2, angle_sorted(iPoinInte))
+ poinInteSort2(1:2, nbPoinInteOut) = poinInteOrigIn(1:2, angle_sorted(iPoinInte))
+ end if
+ end do
+
+ elseif (meshPairing%spaceDime .eq. 2) then
+ poinInteSort1(1, 1) = poinInteTargIn(1, 1)
+ poinInteSort1(1, 2) = poinInteTargIn(1, 1)
+ poinInteSort2(1, 1) = poinInteOrigIn(1, 1)
+ poinInteSort2(1, 2) = poinInteOrigIn(1, 1)
+
+ do iPoinInte = 2, nbPoinInteIn
+ if (poinInteTargIn(1, iPoinInte) .le. poinInteSort1(1, 1) .and. &
+ poinInteTargIn(1, iPoinInte) .ge. (-1.d0)) then
+ poinInteSort1(1, 1) = poinInteTargIn(1, iPoinInte)
+ poinInteSort2(1, 1) = poinInteOrigIn(1, iPoinInte)
+
+ elseif (poinInteTargIn(1, iPoinInte) .ge. poinInteSort1(1, 2) .and. &
+ poinInteTargIn(1, iPoinInte) .le. (1.d0)) then
+ poinInteSort1(1, 2) = poinInteTargIn(1, iPoinInte)
+ poinInteSort2(1, 2) = poinInteOrigIn(1, iPoinInte)
+
+ end if
+ end do
+ nbPoinInteOut = 2
+
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+! ----- Copy
+ if (nbPoinInteOut .le. MAX_NB_INTE) then
+ do iPoinInte = 1, nbPoinInteOut
+ poinInteTargOut(1, iPoinInte) = poinInteSort1(1, iPoinInte)
+ poinInteOrigOut(1, iPoinInte) = poinInteSort2(1, iPoinInte)
+ if (meshPairing%spaceDime == 3) then
+ poinInteTargOut(2, iPoinInte) = poinInteSort1(2, iPoinInte)
+ poinInteOrigOut(2, iPoinInte) = poinInteSort2(2, iPoinInte)
+ end if
+ end do
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! intePoinInCell
+!
+! Check if intersection points are in cell and adjust them with tolerance
+!
+! In meshPairing : main datastructure for pairing
+! In cellGeom : general geometric properties of cell
+! In nbPoinInte : number of intersection points
+! In poinInteIn : list of intersection points
+! Out poinInteOut : list of intersection points after adjustements
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine intePoinInCell(meshPairing, cellGeom, &
+ nbPoinInte, poinInteIn, poinInteOut)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(in) :: meshPairing
+ type(CELL_GEOM), intent(in) :: cellGeom
+ integer, intent(in) :: nbPoinInte
+ real(kind=8), intent(in) :: poinInteIn(2, MAX_NB_INTE)
+ real(kind=8), intent(out) :: poinInteOut(2, MAX_NB_INTE)
+! ----- Local
+ integer :: iPoinInte
+ aster_logical :: pointIsInside
+! ------------------------------------------------------------------------------------------------
+!
+ poinInteOut = 0.d0
+ do iPoinInte = 1, nbPoinInte
+ poinInteOut(:, iPoinInte) = poinInteIn(:, iPoinInte)
+
+!---------- Adjust point inside element
+ call cellPoinAdjust(cellGeom, meshPairing%pairTole, poinInteOut)
+
+! --------- Test if point is inside element
+ pointIsInside = cellPoinInside(cellGeom, meshPairing%pairTole, poinInteOut)
+ ASSERT(pointIsInside)
+
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! inteCellArea
+!
+! Compute area of intersection
+!
+! In spaceDime : dimension of space (2 or 3)
+! In nbPoinInte : number of intersection points
+! In poinInte : list of intersection points
+! Out inteArea : area of intersection
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine inteCellArea(spaceDime, nbPoinInte, poinInte, &
+ inteArea)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ integer, intent(in) :: spaceDime, nbPoinInte
+ real(kind=8), intent(in) :: poinInte(2, MAX_NB_INTE)
+ real(kind=8), intent(out) :: inteArea
+! ----- Local
+ integer :: listPoinNext(MAX_NB_INTE), iPoinInte
+! ------------------------------------------------------------------------------------------------
+!
+ inteArea = 0.d0
+
+! ----- Set index of next points
+ if (spaceDime .eq. 3) then
+ do iPoinInte = 2, nbPoinInte
+ listPoinNext(iPoinInte-1) = iPoinInte
+ end do
+ listPoinNext(nbPoinInte) = 1
+ end if
+
+! ----- Compute area
+ if ((nbPoinInte .gt. 2 .and. spaceDime .eq. 3) .or. &
+ (nbPoinInte .ge. 2 .and. spaceDime .eq. 2)) then
+ if (spaceDime .eq. 3) then
+ do iPoinInte = 1, nbPoinInte
+ inteArea = inteArea+ &
+ poinInte(1, iPoinInte)* &
+ poinInte(2, listPoinNext(iPoinInte))- &
+ poinInte(1, listPoinNext(iPoinInte))* &
+ poinInte(2, iPoinInte)
+ end do
+ inteArea = 1.d0/2.d0*inteArea
+ inteArea = sqrt(inteArea**2)
+ elseif (spaceDime .eq. 2) then
+ inteArea = sqrt((poinInte(1, 2)-poinInte(1, 1))**2)
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! isFatalError
+!
+! Is the error is fatal ?
+!
+! --------------------------------------------------------------------------------------------------
+ function isFatalError(errorPair)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ aster_logical :: isFatalError
+ integer, intent(in) :: errorPair
+! ------------------------------------------------------------------------------------------------
+!
+ isFatalError = ASTER_TRUE
+ if (errorPair .eq. ERR_CELL_ORTH) then
+ isFatalError = ASTER_TRUE
+ elseif (errorPair .eq. ERR_CELL_OOR) then
+ isFatalError = ASTER_TRUE
+ elseif (errorPair .eq. ERR_PAIR_PROJ) then
+ isFatalError = ASTER_FALSE
+ elseif (errorPair .eq. ERR_INTE_VOID) then
+ isFatalError = ASTER_TRUE
+ elseif (errorPair .eq. ERR_PAIR_SLAV) then
+ isFatalError = ASTER_TRUE
+ elseif (errorPair .eq. ERR_PAIR_MAST) then
+ isFatalError = ASTER_TRUE
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end function
+! --------------------------------------------------------------------------------------------------
+!
+! pairAllocate
+!
+! Allocate objects for pairing
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine pairAllocate(pairDime, meshPairing)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ integer, intent(in) :: pairDime
+ type(MESH_PAIRING), intent(inout) :: meshPairing
+! ------------------------------------------------------------------------------------------------
+!
+ AS_ALLOCATE(vi=meshPairing%pair, size=2*pairDime)
+ AS_ALLOCATE(vi=meshPairing%nbPoinInte, size=pairDime)
+ AS_ALLOCATE(vr=meshPairing%poinInte, size=2*pairDime*MAX_NB_INTE)
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! pairDeallocate
+!
+! Deallocate objects for pairing
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine pairDeallocate(meshPairing)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(MESH_PAIRING), intent(inout) :: meshPairing
+! ------------------------------------------------------------------------------------------------
+!
+ AS_DEALLOCATE(vi=meshPairing%pair)
+ AS_DEALLOCATE(vi=meshPairing%nbPoinInte)
+ AS_DEALLOCATE(vr=meshPairing%poinInte)
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! pairAdd
+!
+! Add a pair
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine pairAdd(cellSlavNume, cellMastNume, &
+ nbPoinInte, poinInte, &
+ meshPairing)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ integer, intent(in) :: cellSlavNume, cellMastNume
+ integer, intent(in) :: nbPoinInte
+ real(kind=8), intent(in) :: poinInte(2, MAX_NB_INTE)
+ type(MESH_PAIRING), intent(inout) :: meshPairing
+! ----- Locals
+ integer :: iPoinInte, iPair
+! ------------------------------------------------------------------------------------------------
+!
+ iPair = meshPairing%nbPair+1
+ ASSERT(nbPoinInte .le. MAX_NB_INTE)
+ meshPairing%nbPair = meshPairing%nbPair+1
+ meshPairing%pair(2*(meshPairing%nbPair-1)+1) = cellSlavNume
+ meshPairing%pair(2*(meshPairing%nbPair-1)+2) = cellMastNume
+ meshPairing%nbPoinInte(meshPairing%nbPair) = nbPoinInte
+ do iPoinInte = 1, MAX_NB_INTE
+ meshPairing%poinInte(2*MAX_NB_INTE*(iPair-1)+iPoinInte) = &
+ poinInte(1, iPoinInte)
+ meshPairing%poinInte(2*MAX_NB_INTE*(iPair-1)+MAX_NB_INTE+iPoinInte) = &
+ poinInte(2, iPoinInte)
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! intePoinCoor
+!
+! Compute coordinates of points in real space
+!
+! In cellGeom : general geometric properties of cell
+! In nbPoinInte : number of intersection points
+! In poinInte : list of intersection points (parametric space of cellGeom)
+! Out poinInteReal : list of intersection points after transformation (global space)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine intePoinCoor(cellGeom, nbPoinInte, poinInte, poinInteReal)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellGeom
+ integer, intent(in) :: nbPoinInte
+ real(kind=8), intent(in) :: poinInte(2, MAX_NB_INTE)
+ real(kind=8), intent(out) :: poinInteReal(3, MAX_NB_INTE)
+! ----- Local
+ integer :: iPoinInte
+! ------------------------------------------------------------------------------------------------
+!
+ ASSERT(nbPoinInte .le. MAX_NB_INTE)
+ poinInteReal = 0.d0
+ do iPoinInte = 1, nbPoinInte
+ call cellPoinParaToGlob(cellGeom, &
+ poinInte(:, iPoinInte), poinInteReal(:, iPoinInte))
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! quadPoinCoor
+!
+! Compute coordinates of quadrature points in real space
+!
+! In cellGeom : general geometric properties of cell
+! In nbPoinQuad : number of quadrature points
+! In quadPoinSlav : list of quadrature points (parametric space of cellGeom)
+! Out quadPoinReal : list of quadrature points after transformation (global space)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine quadPoinCoor(cellSlav, nbPoinQuad, quadPoinSlav, quadPoinReal)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellSlav
+ integer, intent(in) :: nbPoinQuad
+ real(kind=8), intent(in) :: quadPoinSlav(2, MAX_NB_QUAD)
+ real(kind=8), intent(out) :: quadPoinReal(3, MAX_NB_QUAD)
+! ----- Local
+ integer :: iPoinQuad
+! ------------------------------------------------------------------------------------------------
+!
+ ASSERT(nbPoinQuad .le. MAX_NB_QUAD)
+ quadPoinReal = 0.d0
+ do iPoinQuad = 1, nbPoinQuad
+ call cellPoinParaToGlob(cellSlav, &
+ quadPoinSlav(:, iPoinQuad), quadPoinReal(:, iPoinQuad))
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! getClosestNodesFromCell
+!
+! Get the closest node in a list from given cell
+!
+! In cellGeom : geometric properties of cell
+! Ptr nodeCoor : pointer to coordinates of nodes
+! In nbNode : number of nodes
+! In listNode : list of nodes
+! Out nodeNumeClosest : index of the closest node (index in mesh)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine getClosestNodesFromCell(cellGeom, nodeCoor, &
+ nbNode, listNode, &
+ nodeNumeClosest)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ type(CELL_GEOM), intent(in) :: cellGeom
+ real(kind=8), pointer :: nodeCoor(:)
+ integer, intent(in) :: nbNode, listNode(nbNode)
+ integer, intent(out) :: nodeNumeClosest
+! ----- Local
+ real(kind=8) :: cellCentGlob(3)
+ integer :: iDime, iNode, nodeNume
+ real(kind=8) :: vect_pm(3), distMini, dist
+! ------------------------------------------------------------------------------------------------
+!
+ nodeNumeClosest = 0
+
+! ----- Get center of cell in global space
+ call cellCompCenterGlob(cellGeom, cellCentGlob)
+
+! ----- Find closest node
+ distMini = 0.d0
+ do iNode = 1, nbNode
+ nodeNume = listNode(iNode)
+ do iDime = 1, 3
+ vect_pm(iDime) = nodeCoor(3*(nodeNume-1)+iDime)-cellCentGlob(iDime)
+ end do
+ dist = sqrt(vect_pm(1)**2+vect_pm(2)**2+vect_pm(3)**2)
+ if (dist .lt. distMini .or. iNode .eq. 1) then
+ distMini = dist
+ nodeNumeClosest = nodeNume
+ end if
+ end do
+ ASSERT(nodeNumeClosest .ne. 0)
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! getCellsFromNode
+!
+! Get list of cells attached to a node
+!
+! In nodeNume : index in mesh of reference node
+! Ptr meshConxInve : pointers to inverse connectivity
+! meshConxInveCumu
+! In nbCell : length of list of cells
+! In listCell : list of cells
+! Out nbCellToNode : length of list of cells attached to node
+! Out cellToNode : list of cells attached to node
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine getCellsFromNode(nodeNume, &
+ meshConxInve, meshConxInveCumu, &
+ nbCell, listCell, &
+ nbCellToNode, cellToNode)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ integer, intent(in) :: nodeNume
+ integer, pointer :: meshConxInve(:), meshConxInveCumu(:)
+ integer, intent(in) :: nbCell
+ integer, intent(in) :: listCell(nbCell)
+ integer, intent(out) :: nbCellToNode
+ integer, intent(out) :: cellToNode(nbCell)
+! ----- Local
+ integer :: iCell
+! ------------------------------------------------------------------------------------------------
+!
+ cellToNode = 0
+ nbCellToNode = meshConxInveCumu(nodeNume+1)-meshConxInveCumu(nodeNume)
+ do iCell = 1, nbCellToNode
+ cellToNode(iCell) = listCell(meshConxInve(meshConxInveCumu(nodeNume)-1+iCell))
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! getPairJV
+!
+! Get pair from JEVEUX object
+!
+! In mesh : mesh
+! In baseName : JEVEUX base name for output objects
+! Ptr nodeCoor : pointer to coordinates of nodes
+! In iPair : index of pair
+! Out cellSlav : slave cell
+! Out cellMast : master cell
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine getPairJV(mesh, baseName, nodeCoor, iPair, cellSlav_, cellMast_)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ character(len=8), intent(in) :: mesh
+ character(len=24), intent(in) :: baseName
+ integer, intent(in) :: iPair
+ real(kind=8), pointer :: nodeCoor(:)
+ type(CELL_GEOM), optional, intent(out) :: cellSlav_, cellMast_
+! ----- Local
+ integer :: jvData
+ type(CELL_GEOM) :: cellSlav, cellMast
+ character(len=24) :: zonePair
+ integer, pointer :: meshTypeGeom(:) => null()
+ integer, pointer :: meshConx(:) => null(), meshConxCumu(:) => null()
+ integer :: nbPair, cellSlavNume, cellMastNume
+! ------------------------------------------------------------------------------------------------
+!
+! ----- Access to mesh
+ call jeveuo(mesh(1:8)//'.TYPMAIL', 'L', vi=meshTypeGeom)
+ call jeveuo(mesh(1:8)//'.CONNEX', 'L', vi=meshConx)
+ call jeveuo(jexatr(mesh(1:8)//'.CONNEX', 'LONCUM'), 'L', vi=meshConxCumu)
+
+! ----- Access to pair objects
+ zonePair = baseName(1:8)//".LISTPAIRS"
+ call jeexin(zonePair, jvData)
+ if (jvData == 0) then
+ call utmess("F", "MESH4_4")
+ end if
+ call jeveuo(zonePair, 'L', jvData)
+ call jelira(zonePair, 'LONMAX', nbPair)
+ if (iPair .le. 0 .or. iPair .gt. nbPair) then
+ call utmess("F", "MESH4_5")
+ end if
+
+! ----- Get current cells in pair
+ cellSlavNume = zi(jvData+2*(iPair-1)-1+1)
+ call cellCreate(cellSlavNume, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ cellSlav)
+
+ !call cellSetType(meshTypeGeom, cellSlavNume, cellSlav)
+ cellMastNume = zi(jvData+2*(iPair-1)-1+2)
+ !call cellSetType(meshTypeGeom, cellMastNume, cellMast)
+ call cellCreate(cellMastNume, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ cellMast)
+
+! ----- Outputs
+ if (present(cellSlav_)) then
+ cellSlav_ = cellSlav
+ end if
+ if (present(cellMast_)) then
+ cellMast_ = cellMast
+ end if
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! getInteJV
+!
+! Get integration points from JEVEUX object
+!
+! In baseName : JEVEUX base name for output objects
+! In iPair : index of pair
+! Out nbPoinInte : number of intersection points
+! Out poinInte : coordinates of intersection points (parametric slave coordinates)
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine getInteJV(baseName, iPair, nbPoinInte, poinInte)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ character(len=24), intent(in) :: baseName
+ integer, intent(in) :: iPair
+ integer, intent(out) :: nbPoinInte
+ real(kind=8), intent(out) :: poinInte(2, MAX_NB_INTE)
+! ----- Local
+ integer :: jvData, iPoinInte
+ character(len=24) :: zonePair, zoneNbPoinInte, zonePoinInte
+ integer :: nbPair
+! ------------------------------------------------------------------------------------------------
+!
+ nbPoinInte = 0
+ poinInte = 0.d0
+
+! ----- Access to pair objects
+ zonePair = baseName(1:8)//".LISTPAIRS"
+ call jeexin(zonePair, jvData)
+ if (jvData == 0) then
+ call utmess("F", "MESH4_4")
+ end if
+ call jeveuo(zonePair, 'L', jvData)
+ call jelira(zonePair, 'LONMAX', nbPair)
+ if (iPair .le. 0 .or. iPair .gt. nbPair) then
+ call utmess("F", "MESH4_5")
+ end if
+
+! ----- Get intersection points
+ zoneNbPoinInte = baseName(1:8)//".NBPOIN"
+ zonePoinInte = baseName(1:8)//".INTERSLPTS"
+ call jeveuo(zoneNbPoinInte, 'L', jvData)
+ nbPoinInte = zi(jvData-1+iPair)
+ call jeveuo(zonePoinInte, 'L', jvData)
+ do iPoinInte = 1, MAX_NB_INTE
+ poinInte(1, iPoinInte) = zr(jvData-1+2*MAX_NB_INTE*(iPair-1)+iPoinInte)
+ poinInte(2, iPoinInte) = zr(jvData-1+2*MAX_NB_INTE*(iPair-1)+MAX_NB_INTE+iPoinInte)
+ end do
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+! --------------------------------------------------------------------------------------------------
+!
+! robustPair
+!
+! Robust pairing on zone
+!
+! In mesh : mesh
+! In newgeo : updated coordinates of nodes
+! In nbCellSlav : number of slave cells
+! In nbCellMast : number of master cells
+! In listCellSlav : list of slave cells
+! In listCellMast : list of master cells
+! IO meshPairing : main datastructure for pairing
+!
+! --------------------------------------------------------------------------------------------------
+ subroutine robustPair(mesh, newgeo, &
+ nbCellSlav, nbCellMast, &
+ listCellSlav, listCellMast, &
+ meshPairing)
+! ------------------------------------------------------------------------------------------------
+! ----- Parameters
+ character(len=8), intent(in) :: mesh
+ character(len=24), intent(in) :: newgeo
+ integer, intent(in) :: nbCellSlav, nbCellMast
+ integer, intent(in) :: listCellMast(nbCellMast), listCellSlav(nbCellSlav)
+ type(MESH_PAIRING), intent(inout) :: meshPairing
+! ----- Local
+ ! aster_logical :: pair_exist, isFatal, l_recup
+ aster_logical :: isFatal
+ ! integer :: nbSlavStart, nbMastStart
+ ! integer, pointer :: cellSlavStart(:) => null()
+ ! integer, pointer :: cellMastStart(:) => null()
+ ! integer, pointer :: cellMastFlag(:) => null()
+ ! integer, pointer :: cellSlavFlag(:) => null(), cellMastPaired(:) => null()
+ ! integer :: slavIndxMini, slavIndxMaxi
+ ! integer :: mastIndxMini, mastIndxMaxi
+ ! integer :: iCell, iMastNeigh, iSlavNeigh
+ integer :: iCellSlav, cellSlavNume, iCellMast, cellMastNume
+ real(kind=8), pointer :: nodeCoor(:) => null()
+ integer, pointer :: meshTypeGeom(:) => null()
+ integer, pointer :: meshConx(:) => null(), meshConxCumu(:) => null()
+ ! integer, pointer :: mastConxInv(:) => null(), mastConxInvCumu(:) => null()
+ type(CELL_GEOM) :: cellSlav, cellMast
+ type(CELL_GEOM) :: cellSlavLine, cellMastLine
+ ! integer :: nbSlavNeigh, nbMastPaired, inteNeigh(MAX_NB_NEIGH), nbMastNeigh
+ ! integer :: cellNeigh(MAX_NB_NEIGH), iret
+ integer :: iret
+ real(kind=8) :: inteArea
+ ! integer :: mastFindIndx, cellMastNume, cellMastIndx, cellSlavIndx, cellSlavNume
+ integer :: nbPoinInte
+ real(kind=8) :: poinInte(2, MAX_NB_INTE), poinInteReal(3, MAX_NB_INTE)
+ ! integer :: cellNeighNume, cellNeighIndx
+ ! integer, pointer :: meshMastNeigh(:) => null(), meshSlavNeigh(:) => null()
+! ------------------------------------------------------------------------------------------------
+!
+ if (meshPairing%debug) then
+ write (6, *) "=================="
+ write (6, *) "= Robust pairing ="
+ write (6, *) "=================="
+ write (6, *) " "
+ end if
+
+! ----- Access to updated geometry
+ call jeveuo(newgeo(1:19)//'.VALE', 'L', vr=nodeCoor)
+
+! ----- Access to mesh
+ call jeveuo(mesh(1:8)//'.TYPMAIL', 'L', vi=meshTypeGeom)
+ call jeveuo(mesh(1:8)//'.CONNEX', 'L', vi=meshConx)
+ call jeveuo(jexatr(mesh(1:8)//'.CONNEX', 'LONCUM'), 'L', vi=meshConxCumu)
+
+! ----- Protection
+ if (nbCellSlav .eq. 0 .or. nbCellMast .eq. 0) then
+ call utmess('F', 'MESH4_1')
+ end if
+
+! ----- Loop on slave cells
+ do iCellSlav = 1, nbCellSlav
+! --------- Get slave element
+ cellSlavNume = listCellSlav(iCellSlav)
+
+! --------- Create slave cell
+ call cellCreate(cellSlavNume, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ cellSlav, cellSlavLine)
+
+ if (meshPairing%debug) then
+ write (6, *) "Current slave element : ", cellSlavNume
+ write (6, *) " Coordinates (global frame): ", &
+ cellSlav%coorNodeGlob(1:meshPairing%spaceDime, 1:cellSlav%nbNode)
+ end if
+
+! --------- Loop on master cells
+ do iCellMast = 1, nbCellMast
+! ------------- Get master element
+ cellMastNume = listCellMast(iCellMast)
+
+! ------------- Create master cell
+ call cellCreate(cellMastNume, nodeCoor, &
+ meshTypeGeom, meshConx, meshConxCumu, &
+ cellMast, cellMastLine)
+ if (meshPairing%debug) then
+ write (6, *) "Current master element: ", cellMastNume
+ write (6, *) " Coordinates (global frame): ", &
+ cellMast%coorNodeGlob(1:meshPairing%spaceDime, 1:cellMast%nbNode)
+ end if
+
+! ------------- Compute intersection of the two cells
+ inteArea = 0.d0
+ nbPoinInte = 0
+ poinInte = 0.d0
+ poinInteReal = 0.d0
+ if (meshPairing%debug) then
+ WRITE (6, *) "Compute intersection and projection in master space"
+ end if
+ call cellInteProj(meshPairing, &
+ cellSlav, cellSlavLine, cellMastLine, &
+ iret, &
+ nbPoinInte, poinInte, &
+ inteArea)
+ isFatal = isFatalError(iret)
+ if (.not. isFatal .and. iret .ne. ERR_PAIR_NONE) then
+ call utmess('A', 'MESH4_3')
+ inteArea = 0.d0
+ nbPoinInte = 0
+ end if
+ ASSERT(nbPoinInte .le. MAX_NB_INTE)
+ if (meshPairing%debug) then
+ WRITE (6, *) "Intersection area: ", inteArea
+ end if
+
+! ------------- Add pair
+ if (inteArea > meshPairing%pairTole .and. iret == ERR_PAIR_NONE) then
+ if (meshPairing%debug) then
+ call intePoinCoor(cellSlav, nbPoinInte, poinInte, poinInteReal)
+ WRITE (6, *) "Add pair: ", meshPairing%nbPair+1, &
+ "(", cellSlavNume, "-", cellMastNume, ")"
+ WRITE (6, *) "Nb points integrations : ", &
+ nbPoinInte
+ WRITE (6, *) "Coor. points integrations (parametric): ", &
+ poinInte(:, 1:nbPoinInte)
+ WRITE (6, *) "Coef. points integrations (global) : ", &
+ poinInteReal(:, 1:nbPoinInte)
+ WRITE (6, *) "Area of intersection : ", &
+ inteArea
+ end if
+ call pairAdd(cellSlavNume, cellMastNume, &
+ nbPoinInte, poinInte, &
+ meshPairing)
+ end if
+ end do
+ end do
+
+! ----- Clean memory
+ ! AS_DEALLOCATE(vi=cellSlavStart)
+ ! AS_DEALLOCATE(vi=cellMastStart)
+ ! AS_DEALLOCATE(vi=cellSlavFlag)
+ ! AS_DEALLOCATE(vi=cellMastFlag)
+ ! AS_DEALLOCATE(vi=cellMastPaired)
+!
+! ------------------------------------------------------------------------------------------------
+ end subroutine
+!
+end module
diff --git a/bibfor/mesh/mesh_pairing_type.F90 b/bibfor/mesh/mesh_pairing_type.F90
new file mode 100644
index 00000000000..86d182a6ff5
--- /dev/null
+++ b/bibfor/mesh/mesh_pairing_type.F90
@@ -0,0 +1,27 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+! aslint: disable=W1403
+module mesh_pairing_type
+!
+ implicit none
+!
+#include "asterf_types.h"
+!
+! false module required because of error in aslint (E1009)
+!
+end module mesh_pairing_type
diff --git a/bibfor/mesh/mesh_type.F90 b/bibfor/mesh/mesh_type.F90
new file mode 100644
index 00000000000..3847b5bb79e
--- /dev/null
+++ b/bibfor/mesh/mesh_type.F90
@@ -0,0 +1,83 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+!
+! ==================================================================================================
+!
+! Module for types of mesh
+!
+! ==================================================================================================
+module mesh_type
+! ==================================================================================================
+! ==================================================================================================
+ implicit none
+! ==================================================================================================
+ private
+#include "asterf_types.h"
+#include "MeshTypes_type.h"
+! ==================================================================================================
+! Global variables
+! ==================================================================================================
+! - None
+! ==================================================================================================
+! Define types
+! ==================================================================================================
+! --------------------------------------------------------------------------------------------------
+! Geometry of a cell
+! --------------------------------------------------------------------------------------------------
+ type CELL_GEOM
+! ----- String for type of cell
+ character(len=8) :: cellCode = " "
+ aster_logical :: isLinear = ASTER_TRUE
+ aster_logical :: isSkin = ASTER_FALSE
+! ----- Topological dimension of cell (-1, 0, 1 or 2)
+ integer :: cellDime = 0
+! ----- Number of nodes
+ integer :: nbNode = 0
+! ----- Number of neighbours
+ integer :: nbNeigh = 0
+! ----- Diameter of cell
+ real(kind=8) :: diameter = -1.d0
+! ----- Barycenter of cell in global basis (X,Y,Z)
+ real(kind=8) :: baryGlob(3) = 0.d0
+! ----- Barycenter of cell in parametric basis (ksi, eta, zeta)
+ real(kind=8) :: baryPara(3) = 0.d0
+! ----- Coordinates of cell in global basis (X,Y,Z)
+ real(kind=8), dimension(3, MT_NNOMAX3D) :: coorNodeGlob = 0.d0
+! ----- Coordinates of cell in parametric basis (ksi, eta, zeta)
+ real(kind=8), dimension(3, MT_NNOMAX3D) :: coorNodePara = 0.d0
+ end type CELL_GEOM
+! --------------------------------------------------------------------------------------------------
+! Base for skin cell
+! --------------------------------------------------------------------------------------------------
+ type CELL_SKIN_BASE
+! ----- Dimension of space
+ integer :: spaceDime = 0
+! ----- Flag for _external_ normal
+ aster_logical :: normIsExte = ASTER_TRUE
+! ----- Normal
+ real(kind=8) :: norm(3) = 0.d0
+! ----- Tangents
+ real(kind=8) :: tau(3, 2) = 0.d0
+ end type CELL_SKIN_BASE
+!===================================================================================================
+!===================================================================================================
+ public :: CELL_GEOM, CELL_SKIN_BASE
+contains
+!===================================================================================================
+!===================================================================================================
+end module mesh_type
diff --git a/bibfor/mesh/pairWrap.F90 b/bibfor/mesh/pairWrap.F90
new file mode 100644
index 00000000000..d917f9a72e9
--- /dev/null
+++ b/bibfor/mesh/pairWrap.F90
@@ -0,0 +1,168 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+!
+subroutine pairWrap(method, &
+ mesh, newgeo, mastConxInvName, &
+ mastNeighName, slavNeighName, &
+ pairTole, distRatio, verbosity, &
+ nbCellMast, listCellMast, &
+ nbCellSlav, listCellSlav, &
+ nbNodeMast, listNodeMast, &
+ nbPairZone, baseName)
+!
+ use MeshPairing_module
+!
+ implicit none
+!
+#include "asterf_types.h"
+#include "asterfort/aplcpgn.h"
+#include "asterfort/assert.h"
+#include "asterfort/dismoi.h"
+#include "asterfort/jedetr.h"
+#include "asterfort/mesh_pairing_type.h"
+#include "asterfort/utmess.h"
+#include "asterfort/wkvect.h"
+#include "jeveux.h"
+!
+ integer, intent(in) :: method
+ character(len=8), intent(in) :: mesh
+ character(len=24), intent(in) :: newgeo, mastConxInvName
+ character(len=24), intent(in) :: mastNeighName, slavNeighName
+ real(kind=8), intent(in) :: pairTole, distRatio
+ integer, intent(in) :: verbosity
+ integer, intent(in) :: nbCellMast, listCellMast(nbCellMast)
+ integer, intent(in) :: nbCellSlav, listCellSlav(nbCellSlav)
+ integer, intent(in) :: nbNodeMast, listNodeMast(nbNodeMast)
+ integer, intent(out) :: nbPairZone
+ character(len=8), intent(in) :: baseName
+!
+! --------------------------------------------------------------------------------------------------
+!
+! Pairing segment to segment
+!
+! Building a list of paired cells by PANG method
+!
+! --------------------------------------------------------------------------------------------------
+!
+! In method : method of pairing
+! In mesh : mesh
+! In newgeo : updated coordinates of nodes
+! In mastConxInvName : name of object for inverse connectivity of master cells on current zone
+! In mastNeighName : name of object for neighbours of master cells
+! In slavNeighName : name of object for neighbours of slave cells
+! In pairTole : tolerance for projection (all operations ! )
+! In distRatio : tolerance from DIST_RATIO
+! In verbosity : level of verbosity
+! In nbCellSlav : number of slave cells
+! In listCellSlav : list of slave cells
+! In nbCellMast : number of master cells
+! In listCellMast : list of master cells
+! In nbNodeMast : number of master nodes
+! In listNodeMast : list of master nodes
+! Out nbPairZone : number of paired cells
+! In baseName : JEVEUX base name for output objects
+! In zonePair : name of datastructure for list of paired cells
+! In zoneNbPoinInte : name of datastructure for number of integration points on slave cell
+! In zonePoinInte : name of datastructure for coordinates of integration points on slave cell
+!
+! --------------------------------------------------------------------------------------------------
+!
+ integer :: pairDime, jvData, spaceDime
+ type(MESH_PAIRING) :: meshPairing
+ character(len=24) :: zonePair, zoneNbPoinInte, zonePoinInte
+!
+! --------------------------------------------------------------------------------------------------
+!
+ nbPairZone = 0
+
+! - Protection
+ if (nbCellSlav .eq. 0 .or. nbCellMast .eq. 0) then
+ call utmess('F', 'MESH4_1')
+ end if
+
+! - Flags for debug
+ meshPairing%debug = verbosity .ge. 2
+
+! - Create main object for pairing
+ pairDime = nbCellMast*nbCellSlav
+ call pairAllocate(pairDime, meshPairing)
+
+! - Tolerances
+ meshPairing%distRatio = distRatio
+ meshPairing%pairTole = pairTole
+
+! - Name of output objects
+ zonePair = baseName(1:8)//".LISTPAIRS"
+ zoneNbPoinInte = baseName(1:8)//".NBPOIN"
+ zonePoinInte = baseName(1:8)//".INTERSLPTS"
+ call jedetr(zonePair)
+ call jedetr(zoneNbPoinInte)
+ call jedetr(zonePoinInte)
+
+! - Get space dimension
+ call dismoi('DIM_GEOM', mesh, 'MAILLAGE', repi=spaceDime)
+ spaceDime = spaceDime
+ if (spaceDime .eq. 2) then
+ spaceDime = 2
+ else
+ spaceDime = 3
+ end if
+ meshPairing%spaceDime = spaceDime
+
+! - Pairing (fast version)
+ if (method == PAIR_FAST) then
+ call fastPair(mesh, newgeo, mastConxInvName, &
+ mastNeighName, slavNeighName, &
+ nbCellSlav, nbCellMast, nbNodeMast, &
+ listCellSlav, listCellMast, listNodeMast, &
+ meshPairing)
+ elseif (method == PAIR_OLD) then
+ call aplcpgn(mesh, newgeo, &
+ mastConxInvName, mastNeighName, slavNeighName, &
+ pairTole, distRatio, &
+ nbCellMast, listCellMast, &
+ nbCellSlav, listCellSlav, &
+ listNodeMast, nbNodeMast, &
+ meshPairing)
+ elseif (method == PAIR_ROBUST) then
+ call robustPair(mesh, newgeo, &
+ nbCellSlav, nbCellMast, &
+ listCellSlav, listCellMast, &
+ meshPairing)
+ else
+ ASSERT(ASTER_FALSE)
+ end if
+
+! - Save results for this zone
+ nbPairZone = meshPairing%nbPair
+ if (nbPairZone > 0) then
+ call wkvect(zonePair, 'G V I', 2*nbPairZone, jvData)
+ zi(jvData-1+1:jvData-1+2*nbPairZone) = &
+ meshPairing%Pair(1:2*nbPairZone)
+ call wkvect(zoneNbPoinInte, 'G V I', nbPairZone, jvData)
+ zi(jvData-1+1:jvData-1+nbPairZone) = &
+ meshPairing%nbPoinInte(1:nbPairZone)
+ call wkvect(zonePoinInte, 'G V R', 2*MAX_NB_INTE*nbPairZone, jvData)
+ zr(jvData-1+1:jvData-1+2*MAX_NB_INTE*nbPairZone) = &
+ meshPairing%poinInte(1:2*MAX_NB_INTE*nbPairZone)
+ end if
+
+! - Clean memory
+ call pairDeallocate(meshPairing)
+!
+end subroutine
diff --git a/bibfor/mesh/quadPoinCoorWrap.F90 b/bibfor/mesh/quadPoinCoorWrap.F90
new file mode 100644
index 00000000000..b7524b53698
--- /dev/null
+++ b/bibfor/mesh/quadPoinCoorWrap.F90
@@ -0,0 +1,92 @@
+! --------------------------------------------------------------------
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+! This file is part of code_aster.
+!
+! code_aster is free software: you can redistribute it and/or modify
+! it under the terms of the GNU General Public License as published by
+! the Free Software Foundation, either version 3 of the License, or
+! (at your option) any later version.
+!
+! code_aster is distributed in the hope that it will be useful,
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+! GNU General Public License for more details.
+!
+! You should have received a copy of the GNU General Public License
+! along with code_aster. If not, see .
+! --------------------------------------------------------------------
+!
+subroutine quadPoinCoorWrap(mesh, nodeCoorName, baseName, iPair, &
+ nbPoinQuad, poinQuad)
+!
+ use MeshPairing_module
+ use mesh_type
+ use mesh_cell_module
+!
+ implicit none
+!
+#include "asterf_types.h"
+#include "asterfort/assert.h"
+#include "asterfort/getQuadCont.h"
+#include "asterfort/jeveuo.h"
+#include "asterfort/mesh_pairing_type.h"
+#include "Contact_type.h"
+#include "jeveux.h"
+!
+ character(len=8), intent(in) :: mesh
+ character(len=24), intent(in) :: nodeCoorName, baseName
+ integer, intent(in) :: iPair
+ integer, intent(out) :: nbPoinQuad
+ real(kind=8), intent(out) :: poinQuad(3, MAX_NB_QUAD)
+!
+! --------------------------------------------------------------------------------------------------
+!
+! Pairing segment to segment
+!
+! Get coordinates of Gauss point in intersection
+!
+! --------------------------------------------------------------------------------------------------
+!
+! In mesh : mesh
+! In baseName : JEVEUX base name for output objects
+! In nodeCoorName : JEVEUX name for coordinates of nodes
+! In iPair : index of pair
+! Out nbPoinQuad : number of quadrature points
+! Out poinQuad : coordinates of quadrature points en global space
+!
+! --------------------------------------------------------------------------------------------------
+!
+ integer:: nbPoinInte
+ real(kind=8) :: poinInteSlav(2, MAX_NB_INTE)
+ real(kind=8) :: poinQuadSlav(2, MAX_NB_QUAD)
+ integer :: modelDime
+ type(CELL_GEOM) :: cellSlav, cellMast
+ real(kind=8), pointer :: nodeCoor(:) => null()
+!
+! --------------------------------------------------------------------------------------------------
+!
+ nbPoinQuad = 0
+ poinQuad = 0.d0
+
+! - Access to updated geometry
+ call jeveuo(nodeCoorName(1:19)//'.VALE', 'L', vr=nodeCoor)
+
+! - Access to pair objects
+ call getPairJV(mesh, baseName, nodeCoor, iPair+1, &
+ cellSlav_=cellSlav, cellMast_=cellMast)
+ ASSERT(cellMast%cellDime .eq. cellSlav%cellDime)
+ modelDime = cellMast%cellDime+1
+
+! - Get coordinates of intersection points in slave parametric space
+ call getInteJV(baseName, iPair+1, nbPoinInte, poinInteSlav)
+
+! - Get quadrature points
+ call getQuadCont(modelDime, &
+ cellSlav%cellCode, cellMast%cellCode, &
+ nbPoinInte, poinInteSlav, &
+ nbPoinQuad, poinQuadSlav)
+
+! - Project coordinates
+ call quadPoinCoor(cellSlav, nbPoinQuad, poinQuadSlav, poinQuad)
+!
+end subroutine
diff --git a/bibfor/op/op0176.F90 b/bibfor/op/op0176.F90
index a0a8ea68289..bee03aa160c 100644
--- a/bibfor/op/op0176.F90
+++ b/bibfor/op/op0176.F90
@@ -1,5 +1,5 @@
! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
+! Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
! This file is part of code_aster.
!
! code_aster is free software: you can redistribute it and/or modify
@@ -26,7 +26,6 @@ subroutine op0176()
#include "asterc/getres.h"
#include "asterfort/assert.h"
#include "asterfort/dyarc0.h"
-#include "asterfort/extrs1.h"
#include "asterfort/extrs2.h"
#include "asterfort/getvid.h"
#include "asterfort/infmaj.h"
@@ -140,15 +139,9 @@ subroutine op0176()
call rscrsd('G', resultOutName, typcon, nbarch)
end if
!
- if (resultInName .eq. resultOutName) then
- if (lrest) call utmess('F', 'PREPOST2_5')
- call extrs1(resultInName, storeNb, storeIndx, paraNb, paraName, &
- nbarch, archi, nbexcl, zk16(jexcl), nbnosy)
- else
- call extrs2(resultInName, resultOutName, typcon, lrest, noma, &
- nomo, nocara, nochmat, storeNb, storeIndx, paraNb, paraName, &
- nbarch, archi, nbexcl, zk16(jexcl), nbnosy)
- end if
+ call extrs2(resultInName, resultOutName, typcon, lrest, noma, &
+ nomo, nocara, nochmat, storeNb, storeIndx, paraNb, paraName, &
+ nbarch, archi, nbexcl, zk16(jexcl), nbnosy)
AS_DEALLOCATE(vi=storeIndx)
!
@@ -173,12 +166,9 @@ subroutine op0176()
!
999 continue
!
-!
-!
! -- CREATION DE L'OBJET .REFD SI NECESSAIRE:
! -------------------------------------------
call refdcp(resultInName, resultOutName)
-!
!
call jedema()
!
diff --git a/bibfor/prepost/extrs1.F90 b/bibfor/prepost/extrs1.F90
deleted file mode 100644
index cd7f7d5e695..00000000000
--- a/bibfor/prepost/extrs1.F90
+++ /dev/null
@@ -1,215 +0,0 @@
-! --------------------------------------------------------------------
-! Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
-! This file is part of code_aster.
-!
-! code_aster is free software: you can redistribute it and/or modify
-! it under the terms of the GNU General Public License as published by
-! the Free Software Foundation, either version 3 of the License, or
-! (at your option) any later version.
-!
-! code_aster is distributed in the hope that it will be useful,
-! but WITHOUT ANY WARRANTY; without even the implied warranty of
-! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-! GNU General Public License for more details.
-!
-! You should have received a copy of the GNU General Public License
-! along with code_aster. If not, see .
-! --------------------------------------------------------------------
-!
-subroutine extrs1(resu0, nbrang, nuordr, nbpara, nompar, &
- nbarch, nuarch, nbexcl, chexcl, nbnosy)
- implicit none
-#include "jeveux.h"
-#include "asterc/isnnem.h"
-#include "asterc/r8vide.h"
-#include "asterfort/assert.h"
-#include "asterfort/copisd.h"
-#include "asterfort/detrsd.h"
-#include "asterfort/extrs3.h"
-#include "asterfort/jedema.h"
-#include "asterfort/jeecra.h"
-#include "asterfort/jemarq.h"
-#include "asterfort/jenuno.h"
-#include "asterfort/jeveuo.h"
-#include "asterfort/jexnum.h"
-#include "asterfort/rsadpa.h"
-#include "asterfort/rsexch.h"
-#include "asterfort/rsmena.h"
-#include "asterfort/rsutch.h"
-!
- integer :: nbrang, nuordr(*), nbarch, nbpara, nuarch(*), nbexcl, nbnosy
- character(len=16) :: nompar(*), chexcl(*)
- character(len=*) :: resu0
-! ------------------------------------------------------------------
-! person_in_charge: jacques.pellet at edf.fr
-! EXTR_RESU / ARCHIVAGE + REUSE
-! ----------------------------------------------------------------------
-!
-!
-! 0.3. ==> VARIABLES LOCALES
-!
-!
- integer :: irang, i, j, k, jtach, iadin, iadou, ire1
- integer :: iundf, iordr
- real(kind=8) :: rundf
- character(len=3) :: type
- character(len=16) :: nomsym
- character(len=16) :: nopara
- character(len=19) :: nomsdr
- character(len=19) :: chamin, nomch1, nomch2
- integer, pointer :: ordr(:) => null()
-! ------------------------------------------------------------------
-!
- call jemarq()
- rundf = r8vide()
- iundf = isnnem()
-!
- nomsdr = resu0
-!
-!
-! 1. -- ON COMPACTE LES CHAMPS ARCHIVES :
-! -------------------------------------------------------
- do i = 1, nbnosy
- call jenuno(jexnum(nomsdr//'.DESC', i), nomsym)
- call jeveuo(jexnum(nomsdr//'.TACH', i), 'E', jtach)
- do j = 1, nbexcl
- if (chexcl(j) .eq. nomsym) then
- do k = 1, nbrang
- if (zk24(jtach+k-1) (1:1) .eq. ' ') goto 10
- call rsexch('F', nomsdr, nomsym, nuordr(k), chamin, &
- ire1)
- call detrsd('CHAMP_GD', chamin)
- zk24(jtach+k-1) = ' '
-10 continue
- end do
- goto 50
-!
- end if
- end do
-!
- irang = 0
- do j = 1, nbrang
- if (zk24(jtach+j-1) (1:1) .eq. ' ') goto 30
- call rsexch('F', nomsdr, nomsym, nuordr(j), chamin, &
- ire1)
- if (nuarch(j) .eq. 0) then
- call detrsd('CHAMP_GD', chamin)
- else
- irang = irang+1
- zk24(jtach+irang-1) = chamin
- end if
-30 continue
- end do
-!
- do k = irang+1, nbrang
- zk24(jtach+k-1) = ' '
- end do
-50 continue
- end do
-!
-!
-! 2. -- ON COMPACTE LES PARAMETRES ARCHIVES :
-! -------------------------------------------
- irang = 0
- do i = 1, nbrang
- if (nuarch(i) .eq. 0) goto 70
- irang = irang+1
- do j = 1, nbpara
- nopara = nompar(j)
- call rsadpa(nomsdr, 'L', 1, nopara, nuordr(i), &
- 1, sjv=iadin, styp=type, istop=0)
- call extrs3(nomsdr, nopara, irang, 'E', 1, &
- type, iadou)
- if (type(1:1) .eq. 'I') then
- zi(iadou) = zi(iadin)
- else if (type(1:1) .eq. 'R') then
- zr(iadou) = zr(iadin)
- else if (type(1:1) .eq. 'C') then
- zc(iadou) = zc(iadin)
- else if (type(1:3) .eq. 'K80') then
- zk80(iadou) = zk80(iadin)
- else if (type(1:3) .eq. 'K32') then
- zk32(iadou) = zk32(iadin)
- else if (type(1:3) .eq. 'K24') then
- zk24(iadou) = zk24(iadin)
- else if (type(1:3) .eq. 'K16') then
- zk16(iadou) = zk16(iadin)
- else if (type(1:2) .eq. 'K8') then
- zk8(iadou) = zk8(iadin)
- end if
- end do
-70 continue
- end do
- ASSERT(irang .eq. nbarch)
-!
-!
-! 3. -- ON COMPACTE LES NUME_ORDRE ARCHIVES :
-! -------------------------------------------
- call jeecra(nomsdr//'.ORDR', 'LONUTI', nbarch)
- call jeveuo(nomsdr//'.ORDR', 'E', vi=ordr)
- irang = 0
- do i = 1, nbrang
- if (nuarch(i) .eq. 0) goto 80
- irang = irang+1
- ordr(irang) = nuordr(i)
-80 continue
- end do
- ASSERT(irang .eq. nbarch)
-!
-!
-! 4. -- ON MET A "ZERO" LES IRANG INUTILISES :
-! -------------------------------------------------
- do irang = nbarch+1, nbrang
- ordr(irang) = iundf
- do j = 1, nbpara
- nopara = nompar(j)
- call extrs3(nomsdr, nopara, irang, 'E', 1, &
- type, iadou)
- if (type(1:1) .eq. 'I') then
- zi(iadou) = iundf
- else if (type(1:1) .eq. 'R') then
- zr(iadou) = rundf
- else if (type(1:1) .eq. 'C') then
- zc(iadou) = dcmplx(rundf, rundf)
- else if (type(1:3) .eq. 'K80') then
- zk80(iadou) = ' '
- else if (type(1:3) .eq. 'K32') then
- zk32(iadou) = ' '
- else if (type(1:3) .eq. 'K24') then
- zk24(iadou) = ' '
- else if (type(1:3) .eq. 'K16') then
- zk16(iadou) = ' '
- else if (type(1:2) .eq. 'K8') then
- zk8(iadou) = ' '
- end if
- end do
- end do
-!
-!
-! 5. -- IL FAUT RENOMMER LES CHAMPS POUR QU'ILS RESPECTENT
-! LA REGLE DE NOMMAGE DE RSUTCH.F :
-! ---------------------------------------------------------
- do i = 1, nbnosy
- call jenuno(jexnum(nomsdr//'.DESC', i), nomsym)
- call jeveuo(jexnum(nomsdr//'.TACH', i), 'E', jtach)
- do j = 1, nbarch
- iordr = ordr(j)
- nomch1 = zk24(jtach-1+j)
- if (nomch1 .eq. ' ') goto 41
- call rsutch(nomsdr, nomsym, iordr, nomch2, .false._1)
- if (nomch1 .ne. nomch2) then
- call copisd('CHAMP', 'G', nomch1, nomch2)
- call detrsd('CHAMP', nomch1)
- zk24(jtach-1+j) = nomch2
- end if
-41 continue
- end do
- end do
-!
-!
-! 6. -- IL FAUT ENCORE DETRUIRE LES SCORIES INUTILES :
-! ----------------------------------------------------
- call rsmena(nomsdr)
-!
- call jedema()
-end subroutine
diff --git a/code_aster/Behaviours/BETON_AGEINGMFront.py b/code_aster/Behaviours/BETON_AGEINGMFront.py
new file mode 100644
index 00000000000..abce9080722
--- /dev/null
+++ b/code_aster/Behaviours/BETON_AGEINGMFront.py
@@ -0,0 +1,41 @@
+# coding=utf-8
+# --------------------------------------------------------------------
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+# This file is part of code_aster.
+#
+# code_aster is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# code_aster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with code_aster. If not, see .
+# --------------------------------------------------------------------
+
+# person_in_charge: goustan.bacquaert at edf.fr
+
+from .cata_comportement import LoiComportementMFront
+
+loi = LoiComportementMFront(
+ nom="BETON_AGEING",
+ lc_type=("MECANIQUE",),
+ doc="""To complete ...""",
+ num_lc=58,
+ nb_vari=0,
+ nom_vari=None,
+ mc_mater=None,
+ modelisation=("3D", "AXIS", "D_PLAN"),
+ deformation=("PETIT", "PETIT_REAC", "GDEF_LOG"),
+ algo_inte=("NEWTON", "NEWTON_PERT"),
+ type_matr_tang=("PERTURBATION", "VERIFICATION"),
+ proprietes=None,
+ syme_matr_tang=("Yes",),
+ exte_vari=None,
+ deform_ldc=("MECANIQUE",),
+ regu_visc=("No",),
+)
diff --git a/code_aster/Cata/Commands/defi_materiau.py b/code_aster/Cata/Commands/defi_materiau.py
index 62d8e685990..6af86ff82d8 100644
--- a/code_aster/Cata/Commands/defi_materiau.py
+++ b/code_aster/Cata/Commands/defi_materiau.py
@@ -98,6 +98,7 @@
EXCLUS("MohrCoulombAS", "MohrCoulombAS_FO"),
EXCLUS("NLH_CSRM", "NLH_CSRM_FO"),
EXCLUS("MCC", "MCC_FO"),
+ EXCLUS("BETON_AGEING", "BETON_AGEING_FO"),
EXCLUS("BETON_BURGER", "BETON_BURGER_FO"),
EXCLUS("MetaAcierEPIL_PT", "MetaAcierEPIL_PT_FO"),
PRESENT_PRESENT("BPEL_ACIER", "ELAS"),
@@ -345,6 +346,8 @@
"Barcelone_FO",
"CSSM",
"CSSM_FO",
+ "BETON_AGEING",
+ "BETON_AGEING_FO",
),
),
reuse=SIMP(statut="c", typ=CO),
@@ -5734,6 +5737,38 @@
FlowCorrection=SIMP(statut="o", typ=fonction_sdaster),
InitVoidsRatio=SIMP(statut="o", typ=fonction_sdaster),
),
+ BETON_AGEING=FACT(
+ statut="f",
+ YoungModulus=SIMP(statut="o", typ="R"),
+ PoissonRatio=SIMP(statut="o", typ="R"),
+ VoigtSphModulus=SIMP(statut="o", typ="R"),
+ VoigtDevModulus=SIMP(statut="o", typ="R"),
+ VoigtSphViscosity=SIMP(statut="o", typ="R"),
+ VoigtDevViscosity=SIMP(statut="o", typ="R"),
+ MaxwellSphModulus=SIMP(statut="o", typ="R"),
+ MaxwellDevModulus=SIMP(statut="o", typ="R"),
+ ConcreteInitTime=SIMP(statut="o", typ="R"),
+ DessiccationModulus=SIMP(statut="o", typ="R"),
+ ArrheniusIndex=SIMP(statut="o", typ="R"),
+ ReferenceTemperature=SIMP(statut="o", typ="R"),
+ KelvinIndex=SIMP(statut="o", typ="R"),
+ ),
+ BETON_AGEING_FO=FACT(
+ statut="f",
+ YoungModulus=SIMP(statut="o", typ=fonction_sdaster),
+ PoissonRatio=SIMP(statut="o", typ=fonction_sdaster),
+ VoigtSphModulus=SIMP(statut="o", typ=fonction_sdaster),
+ VoigtDevModulus=SIMP(statut="o", typ=fonction_sdaster),
+ VoigtSphViscosity=SIMP(statut="o", typ=fonction_sdaster),
+ VoigtDevViscosity=SIMP(statut="o", typ=fonction_sdaster),
+ MaxwellSphModulus=SIMP(statut="o", typ=fonction_sdaster),
+ MaxwellDevModulus=SIMP(statut="o", typ=fonction_sdaster),
+ ConcreteInitTime=SIMP(statut="o", typ=fonction_sdaster),
+ DessiccationModulus=SIMP(statut="o", typ=fonction_sdaster),
+ ArrheniusIndex=SIMP(statut="o", typ=fonction_sdaster),
+ ReferenceTemperature=SIMP(statut="o", typ=fonction_sdaster),
+ KelvinIndex=SIMP(statut="o", typ=fonction_sdaster),
+ ),
NLH_CSRM=FACT(
statut="f",
YoungModulus=SIMP(statut="o", typ="R", val_min=0.000001),
diff --git a/code_aster/Cata/Commands/extr_resu.py b/code_aster/Cata/Commands/extr_resu.py
index 66e6c0d386c..67960ff6439 100644
--- a/code_aster/Cata/Commands/extr_resu.py
+++ b/code_aster/Cata/Commands/extr_resu.py
@@ -1,6 +1,6 @@
# coding=utf-8
# --------------------------------------------------------------------
-# Copyright (C) 1991 - 2022 - EDF R&D - www.code-aster.org
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
# This file is part of code_aster.
#
# code_aster is free software: you can redistribute it and/or modify
@@ -22,6 +22,7 @@
from ..Commons import *
from ..Language.DataStructure import *
from ..Language.Syntax import *
+from ..Language.SyntaxUtils import deprecate
def extr_resu_prod(RESULTAT, **args):
@@ -44,13 +45,20 @@ def extr_resu_prod(RESULTAT, **args):
return AsType(RESULTAT)
+def compat_syntax(keywords):
+ """Compatibility.
+ - reuse is not supported anymore.
+ """
+ if keywords.pop("reuse", None):
+ deprecate("EXTR_RESU/reuse", case=2)
+
+
EXTR_RESU = OPER(
nom="EXTR_RESU",
op=176,
sd_prod=extr_resu_prod,
- reentrant="f:RESULTAT",
fr=tr("Extraire des champs au sein d'une SD Résultat"),
- reuse=SIMP(statut="c", typ=CO),
+ compat_syntax=compat_syntax,
RESULTAT=SIMP(
statut="o",
typ=(
diff --git a/code_aster/Cata/Commons/c_comportement.py b/code_aster/Cata/Commons/c_comportement.py
index defe0f6b5f4..16544bd908f 100644
--- a/code_aster/Cata/Commons/c_comportement.py
+++ b/code_aster/Cata/Commons/c_comportement.py
@@ -316,6 +316,7 @@ def C_COMPORTEMENT(command):
"JOINT_BANDIS",
"NLH_CSRM",
"MCC",
+ "BETON_AGEING",
"Barcelone",
"CSSM",
"LAIGLE",
diff --git a/code_aster/Cata/Commons/c_relation.py b/code_aster/Cata/Commons/c_relation.py
index 76b64fd5700..d2b0ad13f71 100644
--- a/code_aster/Cata/Commons/c_relation.py
+++ b/code_aster/Cata/Commons/c_relation.py
@@ -227,4 +227,5 @@ def C_RELATION(command):
"Barcelone",
"CSSM",
"ELAS_HYPER_VISC",
+ "BETON_AGEING",
)
diff --git a/code_aster/Cata/Language/SyntaxUtils.py b/code_aster/Cata/Language/SyntaxUtils.py
index 35aaca6d973..6e9012e737b 100644
--- a/code_aster/Cata/Language/SyntaxUtils.py
+++ b/code_aster/Cata/Language/SyntaxUtils.py
@@ -1,6 +1,6 @@
# coding=utf-8
# --------------------------------------------------------------------
-# Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
# This file is part of code_aster.
#
# code_aster is free software: you can redistribute it and/or modify
@@ -58,15 +58,15 @@ def deprecate(feature, case=1, help=None, level=6):
level (int): Level of the caller in the stack.
"""
if case == 1:
- msg = "This feature is obsoleted, {0!r} will be removed in the future."
+ msg = "This feature is obsolete, {0!r} will be removed in the future."
elif case == 2:
- msg = "This feature is obsoleted, {0!r} has been removed."
+ msg = "This feature is obsolete, {0!r} has been removed."
elif case == 3:
msg = "This feature has a new implementation, {0!r} will be removed in the future."
elif case == 4:
msg = "This feature has a new implementation, {0!r} has been removed."
else:
- msg = "This feature is obsoleted: {0!r}"
+ msg = "This feature is obsolete: {0!r}"
if help:
msg += " " + help
warn(msg.format(feature), DeprecationWarning, stacklevel=level)
diff --git a/code_aster/CodeCommands/__init__.py b/code_aster/CodeCommands/__init__.py
index 161d22fb43d..f8f7902a9fd 100644
--- a/code_aster/CodeCommands/__init__.py
+++ b/code_aster/CodeCommands/__init__.py
@@ -148,8 +148,6 @@
from .modi_repere import MODI_REPERE
from .norm_mode import NORM_MODE
from .nume_ddl_gene import NUME_DDL_GENE
-
-# other commands are automatically added just using their catalog
from .operator import define_operators
from .post_cham_xfem import POST_CHAM_XFEM
from .post_champ import POST_CHAMP
@@ -189,5 +187,6 @@
from .ther_non_line_mo import THER_NON_LINE_MO
from .variable import VARIABLE
+# other commands are automatically added just using their catalog
define_operators(globals())
del define_operators
diff --git a/code_aster/CodeCommands/calc_champ.py b/code_aster/CodeCommands/calc_champ.py
index 6fb95cf6a99..751c6e55478 100644
--- a/code_aster/CodeCommands/calc_champ.py
+++ b/code_aster/CodeCommands/calc_champ.py
@@ -46,28 +46,24 @@ def post_exec(self, keywords):
Arguments:
keywords (dict): User's keywords.
"""
- if "reuse" not in keywords:
- modele = keywords.get("MODELE")
- if modele is None:
- try:
- modele = keywords["RESULTAT"].getModel()
- except:
- modele = None
- if modele is None:
- try:
- modele = keywords["RESULTAT"].getDOFNumbering().getModel()
- except:
- modele = None
- if modele is not None:
- self._result.setModel(modele)
+ new_model = keywords.get("MODELE")
+ if not new_model:
+ previous = keywords["RESULTAT"].getModels()
+ new_model = previous[-1] if previous else None
+ if not new_model:
+ try:
+ new_model = keywords["RESULTAT"].getDOFNumbering().getModel()
+ except AttributeError:
+ pass
+ if new_model:
+ self._result.setModel(new_model, exists_ok=True)
+ if "reuse" not in keywords:
try:
dofNume = keywords["RESULTAT"].getDOFNumbering()
- except:
- dofNume = None
-
- if dofNume is not None:
self._result.setDOFNumbering(dofNume)
+ except AttributeError:
+ pass
for rank in self._result.getIndexes():
if keywords["RESULTAT"].hasListOfLoads(rank):
@@ -79,19 +75,8 @@ def post_exec(self, keywords):
for fOND in keywords["RESULTAT"].getEquationNumberings():
self._result.addEquationNumbering(fOND)
mesh = keywords["RESULTAT"].getMesh()
- if mesh is not None:
+ if mesh:
self._result.setMesh(mesh)
- else:
- try:
- modele = self._result.getModel()
- except:
- modele = None
-
- if modele is None:
- modele = keywords.get("MODELE")
-
- if modele is not None:
- self._result.setModel(modele)
self._result.build()
@@ -105,27 +90,25 @@ def add_dependencies(self, keywords):
"""
super().add_dependencies(keywords)
self.remove_dependencies(keywords, "RESULTAT")
+ self.remove_dependencies(keywords, "CHAM_UTIL", "FORMULE")
if "reuse" not in keywords:
# only if there is only one model, fieldmat...
try:
models = keywords["RESULTAT"].getModels()
for model in models:
- if model:
- self._result.addDependency(model)
+ self._result.addDependency(model)
except RuntimeError:
pass
try:
fieldmats = keywords["RESULTAT"].getMaterialFields()
for fieldmat in fieldmats:
- if fieldmat:
- self._result.addDependency(fieldmat)
+ self._result.addDependency(fieldmat)
except RuntimeError:
pass
try:
elems = keywords["RESULTAT"].getAllElementaryCharacteristics()
for elem in elems:
- if elem:
- self._result.addDependency(elem)
+ self._result.addDependency(elem)
except RuntimeError:
pass
diff --git a/code_aster/CodeCommands/calc_erreur.py b/code_aster/CodeCommands/calc_erreur.py
index 4cea8a12686..4032e819f0f 100644
--- a/code_aster/CodeCommands/calc_erreur.py
+++ b/code_aster/CodeCommands/calc_erreur.py
@@ -1,6 +1,6 @@
# coding: utf-8
-# Copyright (C) 1991 - 2022 EDF R&D www.code-aster.org
+# Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
#
# This file is part of Code_Aster.
#
@@ -45,11 +45,12 @@ def post_exec(self, keywords):
Arguments:
keywords (dict): User's keywords.
"""
- modele = keywords.get("MODELE")
- if modele is None:
- modele = keywords["RESULTAT"].getModel()
- if modele is not None:
- self._result.setModel(modele)
+ new_model = keywords.get("MODELE")
+ if not new_model:
+ previous = keywords["RESULTAT"].getModels()
+ new_model = previous[-1] if previous else None
+ if new_model:
+ self._result.setModel(new_model, exists_ok=True)
self._result.build()
diff --git a/code_aster/CodeCommands/calc_meta.py b/code_aster/CodeCommands/calc_meta.py
index 5cb39906778..34fa87269ba 100644
--- a/code_aster/CodeCommands/calc_meta.py
+++ b/code_aster/CodeCommands/calc_meta.py
@@ -1,6 +1,6 @@
# coding: utf-8
-# Copyright (C) 1991 - 2022 EDF R&D www.code-aster.org
+# Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
#
# This file is part of Code_Aster.
#
@@ -47,12 +47,13 @@ def post_exec(self, keywords):
Arguments:
keywords (dict): User's keywords.
"""
- modele = keywords["RESULTAT"].getModel()
- if modele is None:
- modele = keywords.get("MODELE")
- if modele is not None:
- self._result.setModel(modele)
- self._result.build()
+ new_model = keywords.get("MODELE")
+ if not new_model:
+ previous = keywords["RESULTAT"].getModels()
+ new_model = previous[-1] if previous else None
+ if new_model:
+ self._result.setModel(new_model, exists_ok=True)
+ self._result.build()
CALC_META = CalcMeta.run
diff --git a/code_aster/CodeCommands/crea_resu.py b/code_aster/CodeCommands/crea_resu.py
index 30c0b7c6f97..2895340889d 100644
--- a/code_aster/CodeCommands/crea_resu.py
+++ b/code_aster/CodeCommands/crea_resu.py
@@ -21,24 +21,23 @@
from ..Helpers import adapt_for_mgis_behaviour
from ..Objects import (
- LoadResult,
- ThermalResult,
- FieldOnNodesComplex,
- FieldOnNodesReal,
- FieldOnNodesChar8,
+ ElasticFourierResult,
+ ElasticResult,
+ ExternalStateVariablesResult,
FieldOnCellsComplex,
- FieldOnCellsReal,
FieldOnCellsLong,
- ElasticFourierResult,
- ThermalFourierResult,
+ FieldOnCellsReal,
+ FieldOnNodesChar8,
+ FieldOnNodesComplex,
+ FieldOnNodesReal,
FullHarmonicResult,
FullTransientResult,
- ExternalStateVariablesResult,
- ElasticResult,
- ModeResultComplex,
+ LoadResult,
ModeResult,
+ ModeResultComplex,
MultipleElasticResult,
NonLinearResult,
+ ThermalResult,
)
from ..Supervis import ExecuteCommand
from ..Utilities import force_list
@@ -89,69 +88,100 @@ def create_result(self, keywords):
raise NotImplementedError("Type of result {0!r} not yet " "implemented".format(typ))
def post_exec(self, keywords):
- """Execute the command.
+ """Hook called after the execution of the command.
Arguments:
keywords (dict): User's keywords.
"""
- fkw = force_list(keywords.get("AFFE", []))
-
- for occ in fkw:
- if occ.get("MODELE"):
- self._result.setModel(occ["MODELE"])
- break
- chamGd = occ.get("CHAM_GD")
- if chamGd is not None:
- if isinstance(chamGd, (FieldOnNodesReal, FieldOnNodesComplex, FieldOnNodesChar8)):
- mesh = chamGd.getMesh()
- if mesh is not None:
- self._result.setMesh(mesh)
- break
-
- # find caraelem
- for occ in fkw:
- if occ.get("CARA_ELEM"):
- self._result.setElementaryCharacteristics(occ["CARA_ELEM"])
- break
+ result = self._result
+ get_ = keywords.get
+
+ new_model = None
+ new_mater = None
+ new_elemcara = None
+ for kw in (
+ "AFFE",
+ "ASSE",
+ "PERM_CHAM",
+ "PROL_RTZ",
+ "PREP_VARC",
+ "KUCV",
+ "CONV_CHAR",
+ "CONV_RESU",
+ ):
+ if kw in keywords:
+ fkw = force_list(keywords[kw])
+
+ if "ASSE" in keywords:
+ src = fkw[0]["RESULTAT"]
+ new_model = src.getModel()
+ new_mater = src.getMaterialField()
+ new_elemcara = src.getElementaryCharacteristics()
+
+ # Model, MaterialField... can not change between occurrences,
+ # the first found is used.
+ if not new_model:
+ new_model = [occ["MODELE"] for occ in fkw if occ.get("MODELE")]
+ new_model = new_model and new_model[0]
+ if not new_mater:
+ new_mater = [occ["CHAM_MATER"] for occ in fkw if occ.get("CHAM_MATER")]
+ new_mater = new_mater and new_mater[0]
+ if not new_elemcara:
+ new_elemcara = [occ["CARA_ELEM"] for occ in fkw if occ.get("CARA_ELEM")]
+ new_elemcara = new_elemcara and new_elemcara[0]
+
+ matr = get_("MATR_RIGI", get_("MATR_MASS"))
+ if matr:
+ result.setDOFNumbering(matr.getDOFNumbering())
+ if not new_model:
+ new_model = matr.getDOFNumbering().getModel()
+ if not new_model and get_("ECLA_PG"):
+ new_model = keywords["ECLA_PG"]["MODELE_INIT"]
+ if not new_model and get_("CONV_CHAR"):
+ matr_rigi = keywords["CONV_CHAR"]["MATR_RIGI"]
+ new_model = matr_rigi.getDOFNumbering().getModel()
+ if not new_model and get_("CONV_RESU"):
+ new_model = keywords["CONV_RESU"]["RESU_INIT"].getModel()
+ if not new_model and get_("KUCV"):
+ new_model = keywords["KUCV"]["RESU_INIT"].getModel()
+
+ if new_model:
+ result.setModel(new_model, exists_ok=True)
+ elif "reuse" not in keywords:
+ # not reuse, at least set the mesh support from AFFE/CHAM_GD or PROL_RTZ
+ if get_("PROL_RTZ"):
+ result.setMesh(keywords["PROL_RTZ"]["MAILLAGE_FINAL"])
+ elif fkw[0].get("CHAM_GD"):
+ mesh = fkw[0]["CHAM_GD"].getMesh()
+ result.setMesh(mesh)
+ if new_elemcara:
+ result.setElementaryCharacteristics(new_elemcara, exists_ok=True)
+ if new_mater:
+ result.setMaterialField(new_mater, exists_ok=True)
# find ligrel and nume_equa
feds = []
fnds = []
for occ in fkw:
- chamGd = occ.get("CHAM_GD")
- if chamGd is not None:
- if isinstance(chamGd, (FieldOnNodesReal, FieldOnNodesComplex, FieldOnNodesChar8)):
- fnd = chamGd.getDescription()
- if fnd is not None:
- fnds.append(fnd)
- elif isinstance(chamGd, (FieldOnCellsReal, FieldOnCellsComplex, FieldOnCellsLong)):
- fed = chamGd.getDescription()
- if fed is not None:
- feds.append(fed)
-
- if keywords.get("MATR_RIGI"):
- self._result.setModel(keywords["MATR_RIGI"].getDOFNumbering().getModel())
- self._result.setMesh(keywords["MATR_RIGI"].getMesh())
- self._result.setDOFNumbering(keywords["MATR_RIGI"].getDOFNumbering())
- elif keywords.get("MATR_MASS"):
- self._result.setModel(keywords["MATR_MASS"].getDOFNumbering().getModel())
- self._result.setMesh(keywords["MATR_MASS"].getMesh())
- self._result.setDOFNumbering(keywords["MATR_MASS"].getDOFNumbering())
-
- if keywords.get("ECLA_PG"):
- self._result.setModel(keywords["ECLA_PG"]["MODELE_INIT"])
- if keywords.get("CONV_CHAR"):
+ chamGd = occ["CHAM_GD"]
+ if isinstance(chamGd, (FieldOnNodesReal, FieldOnNodesComplex, FieldOnNodesChar8)):
+ fnd = chamGd.getDescription()
+ if fnd is not None:
+ fnds.append(fnd)
+ elif isinstance(chamGd, (FieldOnCellsReal, FieldOnCellsComplex, FieldOnCellsLong)):
+ fed = chamGd.getDescription()
+ if fed is not None:
+ feds.append(fed)
+
+ if get_("CONV_CHAR"):
matr_rigi = keywords["CONV_CHAR"]["MATR_RIGI"]
- self._result.setModel(matr_rigi.getDOFNumbering().getModel())
- self._result.setMesh(matr_rigi.getMesh())
dofNum = matr_rigi.getDOFNumbering()
if dofNum:
if keywords["TYPE_RESU"] == "DYNA_TRANS":
- self._result.setDOFNumbering(dofNum)
+ result.setDOFNumbering(dofNum)
else:
fnds.append(dofNum.getEquationNumbering())
- if keywords.get("CONV_RESU"):
- self._result.setModel(keywords["CONV_RESU"]["RESU_INIT"].getModel())
+ if get_("CONV_RESU"):
matr_rigi = keywords["CONV_RESU"].get("MATR_RIGI")
if matr_rigi is not None:
dofNum = matr_rigi.getDOFNumbering()
@@ -159,45 +189,13 @@ def post_exec(self, keywords):
dofNum = keywords["CONV_RESU"]["NUME_DDL"]
if dofNum:
if keywords["TYPE_RESU"] == "DYNA_TRANS":
- self._result.setDOFNumbering(dofNum)
+ result.setDOFNumbering(dofNum)
else:
fnds.append(dofNum.getEquationNumbering())
- if keywords.get("KUCV"):
- self._result.setModel(keywords["KUCV"]["RESU_INIT"].getModel())
+ if get_("KUCV"):
dofNum = keywords["KUCV"]["MATR_AMOR"].getDOFNumbering()
if dofNum:
fnds.append(dofNum.getEquationNumbering())
- if keywords.get("PROL_RTZ"):
- self._result.setMesh(keywords["PROL_RTZ"]["MAILLAGE_FINAL"])
-
- if not fkw:
- fkw = keywords.get("ASSE")
- if not fkw:
- fkw = keywords.get("PREP_VARC")
-
- if fkw:
- chamMater = fkw[0].get("CHAM_MATER")
- if chamMater is not None:
- self._result.setMaterialField(chamMater)
-
- model = fkw[0].get("MODELE")
- chamGd = fkw[0].get("CHAM_GD")
- result = fkw[0].get("RESULTAT")
-
- if model is not None:
- self._result.setModel(model)
- elif result is not None:
- model = result.getModel()
- if model is not None:
- self._result.setModel(model)
-
- mesh = result.getMesh()
- if mesh is not None:
- self._result.setMesh(mesh)
- elif chamGd is not None:
- mesh = chamGd.getMesh()
- if mesh is not None:
- self._result.setMesh(mesh)
self._result.build(feds, fnds)
diff --git a/code_aster/CodeCommands/lire_resu.py b/code_aster/CodeCommands/lire_resu.py
index 06ec1ff7430..d4a50ded441 100644
--- a/code_aster/CodeCommands/lire_resu.py
+++ b/code_aster/CodeCommands/lire_resu.py
@@ -1,6 +1,6 @@
# coding: utf-8
-# Copyright (C) 1991 - 2023 EDF R&D www.code-aster.org
+# Copyright (C) 1991 - 2024 EDF R&D www.code-aster.org
#
# This file is part of Code_Aster.
#
@@ -82,16 +82,15 @@ def post_exec(self, keywords):
keywords (dict): User's keywords.
"""
if "MODELE" in keywords:
- self._result.setModel(keywords["MODELE"])
- self._result.setMesh(keywords["MODELE"].getMesh())
+ self._result.setModel(keywords["MODELE"], exists_ok=True)
elif "MAILLAGE" in keywords:
self._result.setMesh(keywords["MAILLAGE"])
if "CHAM_MATER" in keywords:
- self._result.setMaterialField(keywords["CHAM_MATER"])
+ self._result.setMaterialField(keywords["CHAM_MATER"], exists_ok=True)
if "CARA_ELEM" in keywords:
- self._result.setElementaryCharacteristics(keywords["CARA_ELEM"])
+ self._result.setElementaryCharacteristics(keywords["CARA_ELEM"], exists_ok=True)
if "MATR_RIGI" in keywords:
dofNum = keywords["MATR_RIGI"].getDOFNumbering()
diff --git a/code_aster/CodeCommands/rest_gene_phys.py b/code_aster/CodeCommands/rest_gene_phys.py
index 32803006285..7b2ef54f030 100644
--- a/code_aster/CodeCommands/rest_gene_phys.py
+++ b/code_aster/CodeCommands/rest_gene_phys.py
@@ -79,57 +79,55 @@ def post_exec(self, keywords):
for fED in resu_gene.getFiniteElementDescriptors():
self._result.addFiniteElementDescriptor(fED)
- if dofNum is not None:
+ if dofNum:
self._result.setDOFNumbering(dofNum)
- modele = dofNum.getModel()
- if modele is not None:
- self._result.setModel(modele)
+ model = dofNum.getModel()
+ if model:
+ self._result.setModel(model)
for i in dofNum.getFiniteElementDescriptors():
self._result.addFiniteElementDescriptor(i)
- self._result.setModel(dofNum.getModel())
else:
geneDofNum = resu_gene.getGeneralizedDOFNumbering()
mesh = None
- if geneDofNum is not None:
+ if geneDofNum:
basis = geneDofNum.getModalBasis()
- if basis is not None:
+ if basis:
dofNum = basis.getDOFNumbering()
if mesh is None:
mesh = basis.getMesh()
- if dofNum is not None:
+ if dofNum:
self._result.setDOFNumbering(dofNum)
- modele = dofNum.getModel()
- if modele is not None:
- self._result.setModel(modele)
- elif mesh is None:
+ model = dofNum.getModel()
+ if model:
+ self._result.setModel(model)
+ elif not mesh:
mesh = dofNum.getMesh()
for i in dofNum.getFiniteElementDescriptors():
self._result.addFiniteElementDescriptor(i)
- if mesh is None:
+ if not mesh:
if "MODE_MECA" in keywords:
mesh = keywords["MODE_MECA"].getMesh()
-
- if mesh is not None:
+ if mesh:
self._result.setMesh(mesh)
elif isinstance(resu_gene, GeneralizedModeResult):
self._result.setMesh(resu_gene.getMesh())
matrRigi = resu_gene.getStiffnessMatrix()
- if matrRigi is not None:
+ if matrRigi:
modalBasis = matrRigi.getModalBasis()
if modalBasis is None:
dofNum = matrRigi.getGeneralizedDOFNumbering()
if dofNum:
modalBasis = dofNum.getModalBasis()
- if modalBasis is not None:
+ if modalBasis:
dofNum = modalBasis.getDOFNumbering()
- if dofNum is not None:
+ if dofNum:
self._result.setDOFNumbering(dofNum)
else:
# resultat issue de proj_mesu_modal
dofNum = resu_gene.getDOFNumbering()
- if dofNum is not None:
+ if dofNum:
self._result.setDOFNumbering(dofNum)
elif isinstance(resu_gene, ModeResult):
matrRigiElim = resu_gene.getDependencies()[0]
@@ -145,9 +143,10 @@ def post_exec(self, keywords):
else:
raise Exception("Unknown result type")
- if self._result.getMesh() is None:
+ if not self._result.getMesh():
for fed in feds:
self._result.setMesh(fed.getMesh())
+ break
if self._result.getMesh():
self._result.build(feds, fnds)
diff --git a/code_aster/CodeCommands/stat_non_line.py b/code_aster/CodeCommands/stat_non_line.py
index f418508cd05..5821a30425b 100644
--- a/code_aster/CodeCommands/stat_non_line.py
+++ b/code_aster/CodeCommands/stat_non_line.py
@@ -55,7 +55,7 @@ def create_result(self, keywords):
Arguments:
keywords (dict): Keywords arguments of user's keywords.
"""
- if keywords.get("reuse") is not None:
+ if keywords.get("reuse"):
self._result = keywords["reuse"]
incr = keywords["INCREMENT"][0]
index = incr.get("NUME_INST_INIT")
@@ -73,15 +73,15 @@ def post_exec(self, keywords):
Arguments:
keywords (dict): User's keywords.
"""
- self._result.setModel(keywords["MODELE"])
- self._result.setMaterialField(keywords["CHAM_MATER"])
+ result = self._result
caraElem = keywords.get("CARA_ELEM")
- if caraElem is not None:
- self._result.setElementaryCharacteristics(caraElem)
-
contact = keywords.get("CONTACT")
- if contact is not None:
- self._result.setContact(contact)
+ result.setModel(keywords["MODELE"], exists_ok=True)
+ result.setMaterialField(keywords["CHAM_MATER"], exists_ok=True)
+ if caraElem:
+ result.setElementaryCharacteristics(caraElem, exists_ok=True)
+ if contact:
+ result.setContact(contact)
if self.exception and self.exception.id_message in ("MECANONLINE5_2",):
return
@@ -107,7 +107,7 @@ def post_exec(self, keywords):
feds += etat["EVOL_NOLI"].getFiniteElementDescriptors()
fnds += etat["EVOL_NOLI"].getEquationNumberings()
- self._result.build(feds, fnds)
+ result.build(feds, fnds)
def add_dependencies(self, keywords):
"""Register input *DataStructure* objects as dependencies.
diff --git a/code_aster/Coupling/med_coupler.py b/code_aster/Coupling/med_coupler.py
index 50b145fd821..8aa480e358d 100644
--- a/code_aster/Coupling/med_coupler.py
+++ b/code_aster/Coupling/med_coupler.py
@@ -21,10 +21,10 @@
Definition of a convenient object to synchronize MEDCoupling fields.
"""
-from ..Objects import LoadResult, SimpleFieldOnNodesReal, SimpleFieldOnCellsReal
+from ..Objects import LoadResult, SimpleFieldOnCellsReal, SimpleFieldOnNodesReal
+from ..Utilities import ParaMEDMEM as PMM
from ..Utilities import logger, no_new_attributes
from ..Utilities import medcoupling as MEDC
-from ..Utilities import ParaMEDMEM as PMM
class CoupledField(PMM.ParaFIELD):
diff --git a/code_aster/MacroCommands/CalcEssai/ce_calcul_expansion.py b/code_aster/MacroCommands/CalcEssai/ce_calcul_expansion.py
index 48244c78bbb..7885b07a2ee 100644
--- a/code_aster/MacroCommands/CalcEssai/ce_calcul_expansion.py
+++ b/code_aster/MacroCommands/CalcEssai/ce_calcul_expansion.py
@@ -52,7 +52,7 @@
def extract_mac_array(mac_mode, nom_table="MAC"):
- """!Reconstruit un tableau numpy de modes MAC
+ """Reconstruit un tableau numpy de modes MAC
/param mac_mode concept Table aster
"""
@@ -69,8 +69,7 @@ def extract_mac_array(mac_mode, nom_table="MAC"):
class CalcEssaiExpansion:
-
- """!Classe qui s'occupe des calculs de l'interface correlation
+ """Classe qui s'occupe des calculs de l'interface correlation
Cette classe un peu fourre-tout a pour but de separer les calculs
specifique aster de l'interface graphique. L'objectif etant de pouvoir
@@ -79,7 +78,7 @@ class CalcEssaiExpansion:
"""
def __init__(self, macro, mess, objects):
- """!Constructeur
+ """Constructeur
macro: le self de l'objet macro provenant de calc_essai_ops
"""
@@ -96,7 +95,7 @@ def __init__(self, macro, mess, objects):
self.mess = mess
def __setitem__(self, n, val):
- """!Emulation d'un dictionnaire
+ """Emulation d'un dictionnaire
On implemente __setitem__
pour faire croire au superviseur qu'on cree
@@ -104,7 +103,7 @@ def __setitem__(self, n, val):
self.concepts[n] = val
def __getitem__(self, n):
- """!Emulation d'un dictionnaire
+ """Emulation d'un dictionnaire
On implemente __getitem__ pour les meme raison, et pour
faire de l'allocation dynamique de numero de concept
@@ -124,7 +123,6 @@ def calc_proj_resu(self):
4 resultats sont crees, nommes basename + suffix, ou
suffix = ['_NX','_EX','_ET','_RD']"""
self.mess.disp_mess("Debut de MACRO_EXPANS")
- mdo = self.ce_objects
# Preparation des donnees de mesure
nume = None
@@ -178,7 +176,7 @@ def calc_proj_resu(self):
return result
def calc_mac_mode(self, resu1, resu2, norme):
- """!Calcul de MAC entre deux bases modales compatibles"""
+ """Calcul de MAC entre deux bases modales compatibles"""
try:
__MAC = MAC_MODES(BASE_1=resu1, BASE_2=resu2, MATR_ASSE=norme, INFO=1)
except AsterError as err:
diff --git a/code_aster/MacroCommands/CalcEssai/ce_test.py b/code_aster/MacroCommands/CalcEssai/ce_test.py
index a4cf60786f6..86a1562a6c4 100644
--- a/code_aster/MacroCommands/CalcEssai/ce_test.py
+++ b/code_aster/MacroCommands/CalcEssai/ce_test.py
@@ -1,6 +1,6 @@
# coding=utf-8
# --------------------------------------------------------------------
-# Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
# This file is part of code_aster.
#
# code_aster is free software: you can redistribute it and/or modify
@@ -22,15 +22,11 @@
# Fichier comprenant une procédure de test de CALC_ESSAI avec les différentes
# options de calcul.
-from numpy import take
-
-import aster
from .ce_calcul_modifstruct import CalcEssaiModifStruct
from ...Cata.Syntax import _F
-from ...Messages import UTMESS
from .ce_calcul_expansion import CalcEssaiExpansion
-from .ce_calcul_identification import CalcEssaiIdentification, CalculInverse
+from .ce_calcul_identification import CalcEssaiIdentification
def TestCalcEssai(
@@ -134,7 +130,6 @@ def TestCalcEssai(
class MessageBox:
-
"""!Classe qui permet d'ecrire dans un .mess separe"""
def __init__(self, unite):
diff --git a/code_aster/MacroCommands/Mac3Coeur/mac3coeur_calcul.py b/code_aster/MacroCommands/Mac3Coeur/mac3coeur_calcul.py
index 85292766c10..4cd4e72ef77 100644
--- a/code_aster/MacroCommands/Mac3Coeur/mac3coeur_calcul.py
+++ b/code_aster/MacroCommands/Mac3Coeur/mac3coeur_calcul.py
@@ -80,7 +80,6 @@ def wrapper(inst):
class Mac3CoeurCalcul:
-
"""Base class of an analysis, intended to be inherited
Its factory builds the proper object according to the passed keywords.
@@ -755,7 +754,6 @@ def evaluate_contacts_prediction(self, initial_state_kws, current_load, type_cal
class Mac3CoeurDeformation(Mac3CoeurCalcul):
-
"""Compute the strain of the assemblies"""
mcfact = "DEFORMATION"
@@ -1192,11 +1190,16 @@ def _run(self, **kwargs):
)
logger.debug(": Finish vessel opening using prediction.")
+ logger.debug(
+ "%s (%s), %s",
+ self.cham_mater_free,
+ self.cham_mater_free.getName(),
+ __RESULT.getMaterialField(__RESULT.getLastIndex()),
+ )
return __RESULT
class Mac3CoeurLame(Mac3CoeurCalcul):
-
"""Compute the thinkness of water from deformed assemblies"""
mcfact = "LAME"
@@ -1431,7 +1434,6 @@ def _run(self, **kwargs):
class Mac3CoeurEtatInitial(Mac3CoeurLame):
-
"""Compute Initial State"""
mcfact = "LAME"
diff --git a/code_aster/Messages/contact1.py b/code_aster/Messages/contact1.py
index bea1081b063..4029c825859 100644
--- a/code_aster/Messages/contact1.py
+++ b/code_aster/Messages/contact1.py
@@ -29,15 +29,6 @@
2: _(
"""
Le modèle n'est pas de type mécanique, ce n'est pas possible.
-"""
- ),
- 3: _(
- """
-Il existe des noeuds communs aux surfaces esclaves entre les zones de contact : c'est interdit.
-Conseil :
- - changez vos surfaces de contact,
- - définissez alternativement les zones possédant un noeud commun comme maître et esclave,
- - A MODIFIER pour la méthode LAC, il faut désactiver le lissage.
"""
),
4: _(
diff --git a/code_aster/Messages/mesh4.py b/code_aster/Messages/mesh4.py
new file mode 100644
index 00000000000..ed66e57e6c9
--- /dev/null
+++ b/code_aster/Messages/mesh4.py
@@ -0,0 +1,37 @@
+# coding=utf-8
+# --------------------------------------------------------------------
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
+# This file is part of code_aster.
+#
+# code_aster is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# code_aster is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with code_aster. If not, see .
+# --------------------------------------------------------------------
+
+from ..Utilities import _
+
+cata_msg = {
+ 1: _("""Les surfaces à apparier n'ont pas de cellules."""),
+ # 2: _("""Les cellules de la surface ne sont pas toutes des mailles de peau."""),
+ 3: _(
+ """
+ Une erreur non fatale est détectée lors de l'appariement de deux cellules.
+ Ce couple est ignoré, il y a potentiellement interpénétration entre ces deux cellules.
+ Conseil :
+ Vérifiez la qualité de l'appariement visuellement .
+"""
+ ),
+ 4: _(
+ """On ne trouve pas les objets de l'appariement. Vérifiez que vous avez bien effectué le calcul."""
+ ),
+ 5: _("""La paire demandée n'existe pas à cet index."""),
+}
diff --git a/code_aster/Messages/prepost2.py b/code_aster/Messages/prepost2.py
index edd2263c8f6..5a1ceade193 100644
--- a/code_aster/Messages/prepost2.py
+++ b/code_aster/Messages/prepost2.py
@@ -1,6 +1,6 @@
# coding=utf-8
# --------------------------------------------------------------------
-# Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
# This file is part of code_aster.
#
# code_aster is free software: you can redistribute it and/or modify
@@ -20,11 +20,6 @@
from ..Utilities import _
cata_msg = {
- 5: _(
- """
- Le mot-clé RESTREINT n'est pas autorisé dans EXTR_RESU en reuse.
-"""
- ),
6: _(
"""
Aucune maille n'a été trouvée avec le critère donné.
diff --git a/code_aster/Messages/result2.py b/code_aster/Messages/result2.py
index faa9382a55f..12e13d69ac2 100644
--- a/code_aster/Messages/result2.py
+++ b/code_aster/Messages/result2.py
@@ -1,6 +1,6 @@
# coding=utf-8
# --------------------------------------------------------------------
-# Copyright (C) 1991 - 2023 - EDF R&D - www.code-aster.org
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
# This file is part of code_aster.
#
# code_aster is free software: you can redistribute it and/or modify
@@ -27,6 +27,28 @@
5: _(
"""le numéro d'archivage est inférieur au numéro précédent. Il doit être strictement croissant."""
),
+ 6: _(
+ """Cette opération n'est pas possible si le modèle varie.
+
+Risques & Conseils :
+ Limiter le traitement sur des numéros d'ordre où le modèle ne change pas.
+ """
+ ),
+ 7: _(
+ """Cette opération n'est pas possible si le champ de matériau varie.
+
+Risques & Conseils :
+ Limiter le traitement sur des numéros d'ordre où le champ de matériau ne change pas.
+ """
+ ),
+ 8: _(
+ """Cette opération n'est pas possible si les caractéristiques élémentaires varient.
+
+Risques & Conseils :
+ Limiter le traitement sur des numéros d'ordre où les caractéristiques élémentaires
+ ne changent pas.
+ """
+ ),
14: _("""Le NUME_DDL a été déterminé à partir de la matrice de rigidité %(k1)s."""),
15: _("""Les NUME_DDL associés aux matrices MATR_RIGI et MATR_MASS sont différents."""),
16: _(
diff --git a/code_aster/Supervis/ExecuteCommand.py b/code_aster/Supervis/ExecuteCommand.py
index 45d34e58af7..cce16a77124 100644
--- a/code_aster/Supervis/ExecuteCommand.py
+++ b/code_aster/Supervis/ExecuteCommand.py
@@ -55,9 +55,7 @@
============
"""
-# aslint: disable=C4009
-# because of HELP_LEGACY_MODE string
-
+import gc
import inspect
import linecache
import re
@@ -81,6 +79,7 @@
Options,
config,
deprecated,
+ haveMPI,
import_object,
logger,
no_new_attributes,
@@ -89,7 +88,7 @@
from .code_file import track_coverage
from .CommandSyntax import CommandSyntax
from .ctopy import check_ds_object
-from .Serializer import saveObjectsFromContext
+from .Serializer import FinalizeOptions, saveObjectsFromContext
@contextmanager
@@ -535,6 +534,7 @@ def post_exec_(self, keywords):
if self.hook:
self.hook(keywords)
finally:
+ self.cleanup()
self.print_result()
def post_exec(self, keywords):
@@ -549,6 +549,9 @@ def post_exec(self, keywords):
keywords (dict): Keywords arguments of user's keywords.
"""
+ def cleanup(self):
+ """Clean-up function."""
+
def check_ds(self):
"""Check a result created by the command.
@@ -619,12 +622,6 @@ def check_jeveux():
)
-HELP_LEGACY_MODE = """
- from code_aster.Utilities import ExecutionParameter, Options
- ExecutionParameter().enable(Options.UseLegacyMode)
-"""
-
-
class ExecuteMacro(ExecuteCommand):
"""This implements an executor of *legacy* macro-commands.
@@ -650,6 +647,9 @@ class ExecuteMacro(ExecuteCommand):
_add_results (dict): Dict of additional results.
"""
+ # class attributes
+ _last_cleanup = 0
+
_sdprods = _result_names = _add_results = None
def __init__(self):
@@ -690,6 +690,18 @@ def print_result(self):
logger.info(command_result(self._counter, self.name, self._add_results.get(name)))
self._print_stats()
+ def cleanup(self):
+ """Clean-up function."""
+ if ExecuteCommand.level > 1:
+ if self._counter < ExecuteMacro._last_cleanup + 250:
+ return
+ ExecuteMacro._last_cleanup = self._counter
+ # wrapper to collect after each macro-command
+ timer = ExecutionParameter().timer
+ timer.Start(" . cleanup", num=1.9e6)
+ gc.collect()
+ timer.Stop(" . cleanup")
+
def exec_(self, keywords):
"""Execute the command and fill the *_result* attribute.
@@ -1022,13 +1034,19 @@ def excepthook(cls, type, value, traceb):
except AssertionError:
pass
if cls._current_cmd:
+ opt = ExecutionParameter().option
+ options = FinalizeOptions.Set
+ if haveMPI() and not opt & Options.HPCMode:
+ options |= FinalizeOptions.OnlyProc0
+ if opt & Options.SaveBase:
+ options |= FinalizeOptions.SaveBase
print("\nException: Trying to close the database after an uncaught exception...\n")
print(
f"\nPublishing the result of the current command {cls._current_cmd.name}...\n",
flush=True,
)
cls._current_cmd.publish_result()
- saveObjectsFromContext(cls._current_cmd.caller_context)
+ saveObjectsFromContext(cls._current_cmd.caller_context, options=options)
else:
sys.__excepthook__(type, value, traceb)
diff --git a/code_aster/Supervis/Serializer.py b/code_aster/Supervis/Serializer.py
index 23a777d97c1..6439a7b9f70 100644
--- a/code_aster/Supervis/Serializer.py
+++ b/code_aster/Supervis/Serializer.py
@@ -314,7 +314,7 @@ def saveObjectsFromContext(context, delete=True, options=0):
saved = pickler.save()
else:
saved = []
- logger.info("Objects not saved on processor #%d", rank)
+ logger.info("No database in results, objects not saved on processor #%d", rank)
# close Jeveux files (should not be done before pickling)
libaster.jeveux_finalize(options)
diff --git a/code_aster/Utilities/compatibility.py b/code_aster/Utilities/compatibility.py
index 6a4f1b2f3f1..0d4d734bc45 100644
--- a/code_aster/Utilities/compatibility.py
+++ b/code_aster/Utilities/compatibility.py
@@ -1,6 +1,6 @@
# coding: utf-8
# --------------------------------------------------------------------
-# Copyright (C) 1991 - 2022 - EDF R&D - www.code-aster.org
+# Copyright (C) 1991 - 2024 - EDF R&D - www.code-aster.org
# This file is part of code_aster.
#
# code_aster is free software: you can redistribute it and/or modify
@@ -57,15 +57,15 @@ def deprecate(feature, case=1, help=None, level=4):
level (int): Level of the caller in the stack.
"""
if case == 1:
- msg = "This feature is obsoleted, {0!r} will be " "removed in the future."
+ msg = "This feature is obsolete, {0!r} will be removed in the future."
elif case == 2:
- msg = "This feature is obsoleted, {0!r} has been removed."
+ msg = "This feature is obsolete, {0!r} has been removed."
elif case == 3:
- msg = "This feature has a new implementation, {0!r} will be " "removed in the future."
+ msg = "This feature has a new implementation, {0!r} will be removed in the future."
elif case == 4:
- msg = "This feature has a new implementation, {0!r} has been " "removed."
+ msg = "This feature has a new implementation, {0!r} has been removed."
else:
- msg = "This feature is obsoleted: {0!r}"
+ msg = "This feature is obsolete: {0!r}"
if help:
msg += " " + help
warn(msg.format(feature), DeprecationWarning, stacklevel=level)
@@ -200,7 +200,7 @@ def remove_keyword(keywords, factor_keyword, simple_keyword, warning=False):
def _warn(container, key):
if not warning:
return
- msg = "This keyword is not yet supported and are currently " "removed: {0}{1}{2}"
+ msg = "This keyword is not yet supported and are currently removed: {0}{1}{2}"
sep = "/" if factor_keyword.strip() and simple_keyword.strip() else ""
warn(msg.format(factor_keyword, sep, simple_keyword))
del container[key]
diff --git a/doc/_automatic_/libaster.py b/doc/_automatic_/libaster.py
index 0045d45d283..98005f24a34 100644
--- a/doc/_automatic_/libaster.py
+++ b/doc/_automatic_/libaster.py
@@ -6226,28 +6226,28 @@ def getFiniteElementDescriptor(self):
"""Return the finite element descriptor to define virtual cells for Lagrange multipliers
Returns:
- FiniteElementDescriptor: fed.
+ FiniteElementDescriptor: finite element descriptor
"""
def getMesh(self):
"""Return the mesh used in the contact definition
Returns:
- Mesh: mesh.
+ BaseMesh: mesh.
"""
def getModel(self):
"""Return the model used in the contact definition
Returns:
- Model: model.
+ Model: model
"""
def getNumberOfContactZones(self):
"""Return the number of contact zones used
Returns:
- inter: number of contact zones.
+ int: number of contact zones.
"""
def getVerbosity(self):
@@ -6310,7 +6310,7 @@ def __init__(self, *args, **kwargs):
class ContactZone(DataStructure):
- pass
+ """Object to define a zone of contact."""
# Method resolution order:
# ContactZone
@@ -6329,20 +6329,17 @@ def __init__(self, *args, **kwargs):
"""
def build(self):
- """Build and check internal objects"""
-
- def getContactParameter(self):
- """Get contact parameters defining method, coefficient...
+ """Build and check internal objects
Returns:
- ContactParameter: contact parameters
+ bool: success or failure
"""
- def getExcludedSlaveCells(self):
- """Get excluded groups of cells on slave side
+ def getContactParameter(self):
+ """Get contact parameters defining method, coefficient...
Returns:
- str: excluded groups' names
+ ContactParameter: contact parameters
"""
def getFrictionParameter(self):
@@ -6352,32 +6349,25 @@ def getFrictionParameter(self):
FrictionParameter: friction parameters
"""
- def getMasterCellNeighbors(self, cell_number):
- """Get the master cells in the neighbor of a given master cell number
+ def getMesh(self):
+ """Return the mesh used in the contact zone definition
- Arguments:
- int: master cell number
+ Returns:
+ BaseMesh: mesh
"""
- def getMasterCellsFromNode(self, node_number):
- """Get the master cells associtaed with a node number
-
- Arguments:
- int: node number
- """
-
- def getMesh(self):
- """Return the mesh used in the contact zone definition
+ def getMeshPairing(self):
+ """Get pairing of surface meshes
Returns:
- BaseMesh: mesh.
+ MeshPairing: mesh pairing
"""
def getModel(self):
"""Return the model used in the contact zone definition
Returns:
- Model: model.
+ Model: model
"""
def getPairingParameter(self):
@@ -6387,13 +6377,6 @@ def getPairingParameter(self):
PairingParameter: pairing parameters
"""
- def getSlaveCellNeighbors(self, cell_number):
- """Get the slave cells in the neighbor of a given slave cell number
-
- Arguments:
- int: slave cell number
- """
-
def getSlaveCells(self):
"""Get slave's cells index
@@ -6401,13 +6384,6 @@ def getSlaveCells(self):
list[int]: slave's cells index
"""
- def getSlaveCellsFromNode(self, node_number):
- """Get the slave cells associtaed with a node number
-
- Arguments:
- int: node number
- """
-
def getSlaveNodes(self):
"""Get slave's nodes index
@@ -6416,72 +6392,72 @@ def getSlaveNodes(self):
"""
def getVerbosity(self):
- """Get level of verbosity:
- 0- without
- 1- normal
- 2- detailled
+ """Get level of verbosity
+ 0- without
+ 1- normal
+ 2- detailled
Returns:
- integer: level of verbosity
+ int: level of verbosity
"""
- def setContactParameter(self, contact):
+ def setContactParameter(self, contParam):
"""Set contact parameters defining method, coefficient...
Arguments:
- ContactParameter: contact parameters
+ contParam (ContactParameter) : contact parameters
"""
- def setExcludedSlaveGroupOfCells(self, groups):
+ def setExcludedSlaveGroupOfCells(self, cellGroupsName):
"""Set excluded groups of cells on slave side
Arguments:
- str: excluded groups' names
+ cellGroupsName (str) : excluded groups' names
"""
- def setExcludedSlaveGroupOfNodes(self, groups):
+ def setExcludedSlaveGroupOfNodes(self, nodeGroupsName):
"""Set excluded groups of nodes on slave side
Arguments:
- str: excluded groups' names
+ nodeGroupsName (str) : excluded groups' names
"""
- def setFrictionParameter(self, friction):
+ def setFrictionParameter(self, fricParam):
"""Set friction parameters defining method, coefficient...
Arguments:
- FrictionParameter: friction parameters
+ fricParam (FrictionParameter) : friction parameters
"""
def setMasterGroupOfCells(self, master_name):
"""Set master's name of group of cells
Arguments:
- str: master's name
+ master_name (str) : name of group for master cells
"""
- def setPairingParameter(self, pairing):
+ def setPairingParameter(self, pairParam):
"""Set pairing parameters defining algorithm, distance...
Arguments:
- PairingParameter: pairing parameters
+ pairParam (PairingParameter) : pairing parameters
"""
def setSlaveGroupOfCells(self, slave_name):
"""Set slave's name of group of cells
Arguments:
- str: slave's name
+ slave_name (str) : name of group for slave cells
"""
def setVerbosity(self, level):
- """Set level of verbosity:
- 0- without
- 1- normal (default)
- 2- detailled
+ """Set level of verbosity
+ 0- without
+ 1- normal (default)
+ 2- detailled
Arguments:
- integer: level of verbosity
+ level (int) : level of verbosity
"""
# ----------------------------------------------------------------------
@@ -6489,22 +6465,391 @@ def setVerbosity(self, level):
@property
def checkNormals(self):
- """bool: Attribute that holds the checking of outwards normals."""
+ """bool: attribute that holds the checking of outwards normals."""
@property
def hasFriction(self):
- """bool: enable or disable the use of friction."""
+ """Get status of friction
+
+ Returns:
+ bool: friction or not
+ """
@property
def hasSmoothing(self):
- """bool: enable or disable the use of smoothing."""
+ """Smoothing of normals
+
+ Returns:
+ bool: smoothing or not
+ """
+
+
+# class MeshPairing in libaster
+
+
+class MeshPairing(DataStructure):
+ """Object to create a pairing operator between two meshed surfaces."""
+
+ # Method resolution order:
+ # MeshPairing
+ # DataStructure
+ # pybind11_builtins.pybind11_object
+ # builtins.object
+
+ # Methods defined here:
+
+ def __init__(self, *args, **kwargs):
+ """Overloaded function.
+
+ 1. __init__(self: libaster.MeshPairing, arg0: str, arg1: libaster.BaseMesh) -> None
+
+ 2. __init__(self: libaster.MeshPairing, arg0: libaster.BaseMesh) -> None
+ """
+
+ def checkNormals(self, model):
+ """Check orientation of normals
+
+ Arguments:
+ ModelPtr: a pointer to the model
+
+ Returns:
+ nothing
+ """
+
+ def compute(self, dist_pairing=-1.0, pair_tole=1e-08):
+ """Compute pairing
+
+ Arguments:
+ dist_pairing (real): tolerance from DIST_RATIO (projection outside cell)
+ pair_tole (real): tolerance for pairing
+ """
+
+ def getIntersectionArea(self, *args, **kwargs):
+ """Overloaded function.
+
+ 1. getIntersectionArea(self: libaster.MeshPairing, indexPair: int) -> float
+
+
+ Compute intersection of area
+
+ Arguments:
+ indexPair (integer): index of pair
+
+ Returns:
+ double: area of intersection
+
+
+ 2. getIntersectionArea(self: libaster.MeshPairing, indexPair: int) -> float
+
+
+ Get area of intersection for a given pair
+
+ Arguments:
+ indexPair (integer): index of pair
+
+ Returns:
+ real: area of intersection
+ """
+
+ def getIntersectionPoints(self, indexPair, CoordinatesSpace=1):
+ """Get coordinates of intersection points for a given pair
+
+ Arguments:
+ indexPair (integer): index of pair
+ CoordinatesSpace (CoordinatesSpace): space to describe coordinates
+
+ Returns:
+ list[list]: coordinates in given space
+ """
+
+ def getListOfPairs(self):
+ """Get pairs
+
+ Returns:
+ list: pairs (slave-master)
+ """
+
+ def getMasterCellNeighbors(self, cell_number):
+ """Get the master cells in the neighbor of a given master cell number
+
+ Arguments:
+ int: master cell number
+
+ Returns:
+ list: master neighbors cells
+ """
+
+ def getMasterCellsFromNode(self, node_number):
+ """Get the master cells associated with a node number
+
+ Arguments:
+ int: node number
+
+ Returns:
+ list: master cells associated
+ """
+
+ def getMesh(self):
+ """Return the mesh
+
+ Returns:
+ Mesh: mesh.
+ """
+
+ def getNumberOfIntersectionPoints(self, *args, **kwargs):
+ """Overloaded function.
+
+ 1. getNumberOfIntersectionPoints(self: libaster.MeshPairing, indexPair: int) -> int
+
+
+ Get number of intersection points
+
+ Arguments:
+ indexPair (integer): index of pair
+
+ Returns:
+ integer: number of intersection points
+
+
+ 2. getNumberOfIntersectionPoints(self: libaster.MeshPairing) -> list[int]
+
+
+ Get number of intersection points of all pairs
+
+ Returns:
+ list: number of intersection points
+ """
+
+ def getNumberOfPairs(self):
+ """Get number of pairs
+
+ Returns:
+ integer: number of pairs
+ """
+
+ def getQuadraturePoints(self, indexPair):
+ """Get coordinates of quadrature points for a given pair in global space
+
+ Arguments:
+ indexPair (integer): index of pair
+
+ Returns:
+ list: quadrature points
+ """
+
+ def getSlaveCellNeighbors(self, cell_number):
+ """Get the slave cells in the neighbor of a given slave cell number
+
+ Arguments:
+ int: slave cell number
+
+ Returns:
+ list: slave neighbors cells
+ """
+
+ def getSlaveCellsFromNode(self, node_number):
+ """Get the slave cells associated with a node number
+
+ Arguments:
+ int: node number
+
+ Returns:
+ list: slave cells associated
+ """
+
+ def getVerbosity(self):
+ """Get level of verbosity
+
+ Returns:
+ integer: level of verbosity
+ """
+
+ def setExcludedSlaveGroupOfCells(self, groups):
+ """Set excluded groups of cells on slave side
+
+ Arguments:
+ str: excluded groups' names
+ """
+
+ def setExcludedSlaveGroupOfNodes(self, groups):
+ """Set excluded groups of nodes on slave side
+
+ Arguments:
+ str: excluded groups' names
+ """
+
+ def setMethod(self, method):
+ """Set method of pairing
+
+ Arguments:
+ method (PairingMethod): method ("OLD", "Fast", "Robust)
+ """
+
+ def setPair(self, groupNameSlav, groupNameMast):
+ """Set pair of meshed surfaces
+
+ Arguments:
+ groupNameSlav (str): slave's name
+ groupNameMast (str): master's name
+ """
+
+ def setVerbosity(self, level):
+ """Set level of verbosity
+ 0 - without
+ 1 - normal (default)
+ 2 - detailled (text)
+
+ Arguments:
+ level (integer): level of verbosity
+ """
+
+ def updateCoordinates(self, disp):
+ """Update coordinates of nodes
+
+ Arguments:
+ disp (FieldOnNodesReal): nodal field of displacement
+ """
+
+
+# class CoordinatesSpace in libaster
+
+
+class CoordinatesSpace:
+ """Type of coordinates: Slave or Global."""
+
+ # Method resolution order:
+ # CoordinatesSpace
+ # pybind11_builtins.pybind11_object
+ # builtins.object
+
+ # Methods defined here:
+
+ def __eq__(self, other):
+ pass
+
+ def __getstate__(self):
+ pass
+
+ def __hash__(self):
+ pass
+
+ def __index__(self):
+ pass
+
+ def __init__(self, value):
+ pass
+
+ def __int__(self):
+ pass
+
+ def __ne__(self, other):
+ pass
+
+ def __repr__(self):
+ pass
+
+ def __setstate__(self, state):
+ pass
+
+ def __str__(self):
+ pass
+
+ # ----------------------------------------------------------------------
+ # Data descriptors defined here:
+
+ @property
+ def __members__(self):
+ pass
+
+ @property
+ def name(self):
+ """name(self: object) -> str"""
+
+ @property
+ def value(self):
+ pass
+
+ # ----------------------------------------------------------------------
+ # Data and other attributes defined here:
+
+ Global = 1
+
+ Slave = 0
+
+
+# class PairingMethod in libaster
+
+
+class PairingMethod:
+ """Type of pairing: Fast, BrutForce and Legacy."""
+
+ # Method resolution order:
+ # PairingMethod
+ # pybind11_builtins.pybind11_object
+ # builtins.object
+
+ # Methods defined here:
+
+ def __eq__(self, other):
+ pass
+
+ def __getstate__(self):
+ pass
+
+ def __hash__(self):
+ pass
+
+ def __index__(self):
+ pass
+
+ def __init__(self, value):
+ pass
+
+ def __int__(self):
+ pass
+
+ def __ne__(self, other):
+ pass
+
+ def __repr__(self):
+ pass
+
+ def __setstate__(self, state):
+ pass
+
+ def __str__(self):
+ pass
+
+ # ----------------------------------------------------------------------
+ # Data descriptors defined here:
+
+ @property
+ def __members__(self):
+ pass
+
+ @property
+ def name(self):
+ """name(self: object) -> str"""
+
+ @property
+ def value(self):
+ pass
+
+ # ----------------------------------------------------------------------
+ # Data and other attributes defined here:
+
+ BrutForce = 2
+
+ Fast = 0
+
+ Legacy = 1
# class ContactPairing in libaster
class ContactPairing(DataStructure):
- pass
+ """Object to create contact pairing."""
# Method resolution order:
# ContactPairing
@@ -6522,31 +6867,50 @@ def __init__(self, *args, **kwargs):
2. __init__(self: libaster.ContactPairing, arg0: libaster.ContactNew) -> None
"""
- def clear(self):
- """clean all the paring quantities of all zones
+ def clearPairing(self, *args, **kwargs):
+ """Overloaded function.
+
+ 1. clearPairing(self: libaster.ContactPairing) -> None
+
+
+ Clean pairing for all zones
+
Returns:
bool: true if the pairing quantities are cleared
- """
- def clearZone(self, zone_index):
- """clean all the paring quantities of zone zonde_index
+
+ 2. clearPairing(self: libaster.ContactPairing, zone_index: int) -> None
+
+
+ Clean pairing for a zone
+
Arguments:
- zone_index(int)
+ zone_index(int) : index of zone
+
Returns:
bool: true if the pairing quantities are cleared
"""
- def compute(self):
- """Compute the pairing quantities associated with the zones
+ def compute(self, *args, **kwargs):
+ """Overloaded function.
+
+ 1. compute(self: libaster.ContactPairing) -> bool
+
+
+ Compute the pairing quantities on all zones
Returns:
bool: True if the pairing quantities are updated appropriately
- """
- def computeZone(self, zone_index):
- """Compute the pairing quantities associated with the zone zone_index
+
+ 2. compute(self: libaster.ContactPairing, zone_index: int) -> bool
+
+
+ Compute the pairing quantities on a zone
+
Arguments:
zone_index(int)
+
Returns:
bool: True if the pairing quantities are updated appropriately
"""
@@ -6555,7 +6919,7 @@ def getCoordinates(self):
"""Coordinates of nodes used for pairing (almost always different from the intial mesh).
Returns:
- MeshCoordinatesFieldPtr: the coordinates field
+ MeshCoordinatesField: the coordinates field
"""
def getFiniteElementDescriptor(self):
@@ -6565,37 +6929,93 @@ def getFiniteElementDescriptor(self):
FiniteElementDescriptor: finite element for virtual cells
"""
- def getListOfPairsOfZone(self, zone_index):
- """return list of pairs associated with the zone izone
+ def getIntersectionPoints(self, zone_index, CoordinatesSpace=1):
+ """Get the intersection points between master and slave cells
+
+ Arguments:
+ zone_index(int) : index of zone
+ CoordinatesSpace (CoordinatesSpace): space to describe coordinates
+
+ Returns:
+ list[pair]: list of pair of coordinates of intersection points
+ """
+
+ def getListOfPairs(self, *args, **kwargs):
+ """Overloaded function.
+
+ 1. getListOfPairs(self: libaster.ContactPairing, zone_index: int) -> list[tuple[int, int]]
+
+
+ Get list of contact pairs for a contact zone
+
Arguments:
zone_index(int)
+
+ Returns:
+ list[tuple[int, int]]: list of contact pairs
+
+
+ 2. getListOfPairs(self: libaster.ContactPairing) -> list[tuple[int, int]]
+
+
+ Get list of contact pairs on all zones
+
Returns:
- List[List[int]]: List of pairs
+ list[tuple[int, int]]: list of contact pairs
"""
- def getNumberOfPairs(self):
- """return the total number of pairs
+ def getMesh(self):
+ """Mesh
+
Returns:
- int: Total number of pairs
+ BaseMesh: the mesh
"""
- def getNumberOfPairsOfZone(self, zone_index):
- """return number of pairs associated with the zone zone_index
+ def getNumberOfIntersectionPoints(self, zone_index):
+ """Get list of the number of intersection points beetween a master and slave cells.
+
+ Arguments:
+ zone_index(int) : index of zone
+
+ Returns:
+ list: list of number of intersection points
+ """
+
+ def getNumberOfPairs(self, *args, **kwargs):
+ """Overloaded function.
+
+ 1. getNumberOfPairs(self: libaster.ContactPairing) -> int
+
+
+ Return number of pairs on all zones
+
+ Returns:
+ int: number of pairs
+
+
+ 2. getNumberOfPairs(self: libaster.ContactPairing, zone_index: int) -> int
+
+
+ Return the number of pairs on a zone
+
Arguments:
zone_index(int)
Returns:
int: number of pairs
"""
- def getSlaveIntersectionPoints(self, zone_index):
- """Get the intersection points beetween a master and slave cells in the parametric
- slave space. The maximum number of points is 8.
+ def getNumberOfZones(self):
+ """Return the number of zones
- Arguments:
- zone_index(int) : index of zone
+ Returns:
+ int: number of zones
+ """
+
+ def getVerbosity(self):
+ """Get level of verbosity
Returns:
- list[list]: list of list of intersection points (each intersection is of size 16)
+ integer: level of verbosity
"""
def setCoordinates(self, coordinates):
@@ -6605,8 +7025,22 @@ def setCoordinates(self, coordinates):
coordinates (MeshCoordinatesField) : coordinates to use for pairing
"""
+ def setVerbosity(self, verbosity):
+ """Set level of verbosity
+ 0 - without
+ 1 - normal (default)
+ 2 - detailled (text)
+
+ Arguments:
+ level (integer): level of verbosity
+ """
+
def updateCoordinates(self, disp):
- """Update the mesh coordinates given a displacement field"""
+ """Update the mesh coordinates given a displacement field
+
+ Arguments:
+ disp (FieldOnNodes) : field for displacement
+ """
# class ContactComputation in libaster
@@ -6632,16 +7066,15 @@ def __setstate__(self, arg0):
pass
def contactCoefficient(self):
- """Compute contact coefficient at the nodes of the slave surface based on values of COEF_CONT
+ """Compute contact coefficients at the nodes of the slave surface based on values of COEF_CONT
and COEF_FROT
Returns:
- FieldOnNodesReal: contact coefficient (= COEF_CONT)
- FieldOnNodesReal: friction coefficient (= COEF_FROT)
+ list[FieldOnNodesReal]: coefficients (COEF_CONT and COEF_FROT)
"""
def contactData(self, pairing, material, initial_contact):
- """Compute contact data (cf. MMCHML) as input to compute contact forces and matrices.
+ """Compute contact data as input to compute contact forces and matrices.
Arguments:
pairing (ContactPairing): pairing object
@@ -6652,6 +7085,26 @@ def contactData(self, pairing, material, initial_contact):
FieldOnCellsReal: contact data
"""
+ def getVerbosity(self):
+ """Get level of verbosity
+ 0- without
+ 1- normal
+ 2- detailled
+
+ Returns:
+ int: level of verbosity
+ """
+
+ def setVerbosity(self, level):
+ """Set level of verbosity
+ 0- without
+ 1- normal (default)
+ 2- detailled
+
+ Arguments:
+ level (int) : level of verbosity
+ """
+
# class BaseAssemblyMatrix in libaster
diff --git a/doc/_automatic_/objects_DataStructure.rst b/doc/_automatic_/objects_DataStructure.rst
index 72d135be857..a133823afac 100644
--- a/doc/_automatic_/objects_DataStructure.rst
+++ b/doc/_automatic_/objects_DataStructure.rst
@@ -1081,6 +1081,15 @@ Subclasses of :py:class:`~code_aster.Objects.DataStructure`
:members:
+********************************************************************************
+:py:class:`~code_aster.Objects.MeshPairing` object
+********************************************************************************
+
+.. autoclass:: code_aster.Objects.MeshPairing
+ :show-inheritance:
+ :members:
+
+
********************************************************************************
:py:class:`~code_aster.Objects.MeshesMapping` object
********************************************************************************
diff --git a/doc/_automatic_/objects_Others.rst b/doc/_automatic_/objects_Others.rst
index b399e64437c..5f6d4d25c29 100644
--- a/doc/_automatic_/objects_Others.rst
+++ b/doc/_automatic_/objects_Others.rst
@@ -83,6 +83,15 @@ Documentation of all other types.
:members:
+********************************************************************************
+:py:class:`~code_aster.Objects.CoordinatesSpace` object
+********************************************************************************
+
+.. autoclass:: code_aster.Objects.CoordinatesSpace
+ :show-inheritance:
+ :members:
+
+
********************************************************************************
:py:class:`~code_aster.Objects.CrackShape` object
********************************************************************************
@@ -438,6 +447,15 @@ Documentation of all other types.
:members:
+********************************************************************************
+:py:class:`~code_aster.Objects.PairingMethod` object
+********************************************************************************
+
+.. autoclass:: code_aster.Objects.PairingMethod
+ :show-inheritance:
+ :members:
+
+
********************************************************************************
:py:class:`~code_aster.Objects.PairingParameter` object
********************************************************************************
diff --git a/doc/_automatic_/table_DataStructure.rst b/doc/_automatic_/table_DataStructure.rst
index 2fd1aedc968..06e1636a366 100644
--- a/doc/_automatic_/table_DataStructure.rst
+++ b/doc/_automatic_/table_DataStructure.rst
@@ -249,6 +249,8 @@
- ``maillage_sdaster``
* - :py:class:`~code_aster.Objects.MeshCoordinatesField`
-
+ * - :py:class:`~code_aster.Objects.MeshPairing`
+ -
* - :py:class:`~code_aster.Objects.MeshesMapping`
- ``corresp_2_mailla``
* - :py:class:`~code_aster.Objects.ModeResult`
diff --git a/doc/_automatic_/table_Others.rst b/doc/_automatic_/table_Others.rst
index 3d54b5eb621..9c4e68def0b 100644
--- a/doc/_automatic_/table_Others.rst
+++ b/doc/_automatic_/table_Others.rst
@@ -18,6 +18,7 @@
* - :py:class:`~code_aster.Objects.ContactParameter`
* - :py:class:`~code_aster.Objects.ContactType`
* - :py:class:`~code_aster.Objects.ContactVariant`
+ * - :py:class:`~code_aster.Objects.CoordinatesSpace`
* - :py:class:`~code_aster.Objects.CrackShape`
* - :py:class:`~code_aster.Objects.DiscreteComputation`
* - :py:class:`~code_aster.Objects.DisplacementReal`
@@ -58,6 +59,7 @@
* - :py:class:`~code_aster.Objects.NormalSpeedReal`
* - :py:class:`~code_aster.Objects.ObjectBalancer`
* - :py:class:`~code_aster.Objects.PairingAlgo`
+ * - :py:class:`~code_aster.Objects.PairingMethod`
* - :py:class:`~code_aster.Objects.PairingParameter`
* - :py:class:`~code_aster.Objects.ParMetisPartitioner`
* - :py:class:`~code_aster.Objects.PartOfMaterialField`
diff --git a/mfront/BETON_AGEING.mfront b/mfront/BETON_AGEING.mfront
new file mode 100644
index 00000000000..d51477c7183
--- /dev/null
+++ b/mfront/BETON_AGEING.mfront
@@ -0,0 +1,150 @@
+@Parser Default;
+@Behaviour BETON_AGEING;
+@Author Goustan Bacquaert;
+@Date 06/11/2024;
+
+/// >>>>>>>>>>>>>>>>>>>
+/// Material properties
+/// <<<<<<<<<<<<<<<<<<<
+
+@MaterialProperty stress young; // Young modulus [Pa]
+@MaterialProperty stress nu; // Poisson coefficient [-]
+@MaterialProperty stress Kv_vt; // Volumetric stiffness in the Voigt element [Pa]
+@MaterialProperty stress Kd_vt; // Deviatoric stiffness in the Voigt element [Pa]
+@MaterialProperty real Etav_vt; // Volumetric viscosity in the Voigt element [Pa.s]
+@MaterialProperty real Etad_vt; // Deviatoric viscosity in the Voigt element [Pa.s]
+@MaterialProperty stress Kv_mx; // Stress slope of the time-dependent volumetric viscosity in the Maxwell element [Pa]
+@MaterialProperty stress Kd_mx; // Stress slope of the time-dependent deviatoric viscosity in the Maxwell element [Pa]
+@MaterialProperty real t0; // Concrete pouring instant [s]
+@MaterialProperty real Ea_R; // Molar activation energy / universal gas constant [K]
+@MaterialProperty real M_RhoR; // Steam molar mass / (water mass density x universal gas constant) [Pa^-1]
+@MaterialProperty real Tref; // Reference temperature [K]
+@MaterialProperty real K_fd; // Modulus of the dessiccation creep [Pa]
+
+young.setGlossaryName("YoungModulus");
+nu.setGlossaryName("PoissonRatio");
+Kv_vt.setEntryName("VoigtSphModulus");
+Kd_vt.setEntryName("VoigtDevModulus");
+Etav_vt.setEntryName("VoigtSphViscosity");
+Etad_vt.setEntryName("VoigtDevViscosity");
+Kv_mx.setEntryName("MaxwellSphModulus");
+Kd_mx.setEntryName("MaxwellDevModulus");
+t0.setEntryName("ConcreteInitTime");
+K_fd.setEntryName("DessiccationModulus");
+Tref.setEntryName("ReferenceTemperature");
+Ea_R.setEntryName("ArrheniusIndex");
+M_RhoR.setEntryName("KelvinIndex");
+
+/// >>>>>>>>>>>>>>>
+/// Local variables
+/// <<<<<<<<<<<<<<<
+
+@LocalVariable Stensor4 id4; // Identity or order 4
+@LocalVariable Stensor4 k4; // Deviatoric projector of order 4
+@LocalVariable Stensor4 j4; // Spheric projector of order 4
+@LocalVariable Stensor4 C_el; // Elastic stiffness
+@LocalVariable Stensor4 C_vt; // Stiffness in the Voigt element
+@LocalVariable Stensor4 V_vt; // Viscosity in the Voigt element
+@LocalVariable Stensor4 V_mx; // Viscosity tensor in the Maxwell element
+@LocalVariable real rH; // Relative humidity
+@LocalVariable real drH; // Relative humidity increment
+@LocalVariable real VrH; // = -drH iff drH < 0 and rH < rHmin+1
+
+/// >>>>>>>>>>>>>>>>>>>>>>>>
+/// External state variables
+/// <<<<<<<<<<<<<<<<<<<<<<<<
+
+@ExternalStateVariable real PCAP; // Capillary pressure at !!previous!! time-step
+@ExternalStateVariable real TIME; // Time at !!current!! time-step
+
+PCAP.setEntryName("CapillaryPressure");
+TIME.setEntryName("Time");
+
+/// >>>>>>>>>>>>>>>>>>>>>>>>>
+/// Auxiliary state variables
+/// <<<<<<<<<<<<<<<<<<<<<<<<<
+
+@AuxiliaryStateVariable Stensor efr; // Reversible creep strain
+@AuxiliaryStateVariable Stensor efi; // Irreversible creep strain
+@AuxiliaryStateVariable Stensor efd; // Dessiccation creep strain
+@AuxiliaryStateVariable real rHmin; // Shifted historical minimum relative humidity
+
+efr.setEntryName("RevCreepStrain");
+efi.setEntryName("IrrCreepStrain");
+efd.setEntryName("DesCreepStrain");
+rHmin.setEntryName("ShiftMiniRelaHumi");
+
+/// >>>>>>>>>>>>>>>>>>>>
+/// Init local variables
+/// <<<<<<<<<<<<<<<<<<<<
+
+@InitLocalVariables{
+ // Initialize invariant projection tensors
+ k4 = Stensor4::K();
+ j4 = Stensor4::J();
+ id4 = Stensor4::Id();
+
+ // Initialize the Arrhenius coefficient
+ const real expT = exp(Ea_R*((1./(T+dT/2.)-1./(Tref))));
+
+ // Initialize the relative humiditidy
+ rH = exp(-(PCAP+0.5*dPCAP)*M_RhoR/(T+dT/2.));
+ drH = exp(-(PCAP+dPCAP)*M_RhoR/(T+dT))-exp(-PCAP*M_RhoR/T);
+
+ // Compute the dessiccation creep strain source term
+ if ((drH <= 0.) && (rH <= rHmin+1.)){
+ VrH = -drH;
+ rHmin = rH-1.;
+ }
+ else{
+ VrH = 0.;
+ }
+
+ // Initialize the elastic stiffness
+ C_el = young/(1.-2.*nu)*j4+young/(1.+nu)*k4;
+
+ // Initialize the stiffness and the viscosity in the Voigt element, taken into account the temperature and relative humidity influence
+ C_vt = expT*(3.*Kv_vt*j4+2.*Kd_vt*k4)/rH;
+ V_vt = expT*(3.*Etav_vt*j4+2.*Etad_vt*k4)/rH;
+
+ // Initialize viscosity in the Maxwell element, taken into account the temperature and relative humidity influence
+ V_mx = expT*(3.*Kv_mx*j4+2.*Kd_mx*k4)/rH*max(TIME-0.5*dt-t0,0.);
+}
+
+/// >>>>>>>>>>>>>>>>>>
+/// Elastic prediction
+/// <<<<<<<<<<<<<<<<<<
+
+@PredictionOperator{
+ Dt = C_el;
+}
+
+/// >>>>>>>>>>>
+/// Integration
+/// <<<<<<<<<<<
+
+@Integrator{
+ // Compute the tangent compliance
+ const Stensor4 St = invert(C_el)+dt*invert(dt*C_vt+V_vt)+dt*invert(V_mx)+VrH/K_fd*id4;
+
+ // Compute the stress
+ sig = invert(St)*(eto+deto-invert(dt*C_vt+V_vt)*V_vt*efr-efi-efd);
+}
+
+/// <<<<<<<<<<<<<<<<
+/// Tangent operator
+/// >>>>>>>>>>>>>>>>
+
+@TangentOperator{
+ Dt = invert(invert(C_el)+dt*invert(dt*C_vt+V_vt)+dt*invert(V_mx)+VrH/K_fd*id4);
+}
+
+/// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+/// Update auxiliary state variables
+/// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+@UpdateAuxiliaryStateVariables {
+ efr += dt*invert(dt*C_vt+V_vt)*(sig-C_vt*efr);
+ efi += dt*invert(V_mx)*sig;
+ efd += VrH/K_fd*sig;
+}